2017-09-25 112 views
1

我正在学习承诺库,但坚持以下问题。承诺不会等待超时

//Function for getting sum 
    function getSum(n1, n2) { 
     var isAnyNegative = function() { 
      return n1 < 0 || n2 < 0; 
     } 
     var promise = new Promise(function(resolve, reject) { 
      if (isAnyNegative()) { 
      reject(Error("Negatives not supported")); 
      } 
      resolve(n1 + n2) 
     }); 
     return promise; 
    } 

////Function for getting Difference 
    function getDiff(n1,n2){ 
     var diff = n1-n2; 
     setTimeout(function(){ 
      console.log("value of diff--- ", diff) 
      return diff; 
     }, 2000) 
    } 

    getSum(5,6) 
    .then(function(callbackResult){ 
     console.log("first callback-Result- ", callbackResult) 
     return getDiff(14,11); 
    }, function(error){ 
     //handling error 
    }) 
    .then(function(callbackResult){ 
     console.log("second callback--Result- ", callbackResult) 
     return getSum(22,22); 
    }, 
    function(error){ 
     //handling error 
    }) 
    .then(function(callbackResult){ 
     console.log("third callback--Result- ", callbackResult) 
    }, function(error){ 
     //handling error 
    }) 

我得到这个代码片段的输出: -

first callback-Result- 11 
second callback--Result- undefined 
third callback--Result- 44 
value of diff--- 3 

为什么没有第二个回调等待差函数返回。我认为这是Promise库同步代码的主要特点。

+2

是的,它是有点。但setTimeout是一个异步调用以及 –

+0

看@GrégoryNEUT的答案。事实上,当你在超时返回时,你不会返回diff函数。这同样适用于,例如'map'方法。函数x(){ array.map(function(el){return el}); }' 当调用'x()'时,它不会返回列表中的第一个元素。 – SBylemans

回答

4

您必须以异步方式处理setTimeout。例如:

function getDiff(n1,n2){ 
    return new Promise((resolve) => { 
     const diff = n1 - n2; 

     setTimeout(() => { 
      console.log('value of diff--- ', diff); 

      return resolve(diff); 
     }, 2000); 
    } 
}); 
+0

如果您使用[Bluebird](http://bluebirdjs.com/docs/api/promise.delay.html)库,另一个选择是使用'Bluebird.delay(2000)',等待2秒钟,然后解决返回的承诺。 – Griffin

+0

@Griffin是的,你可以做到这一点,但是为什么当'node.js'确实支持原生''Promises'时,为什么要使用'Bluebird'? –

+1

绝对是一个好点,es6正在获得许多新东西。尽管本机JavaScript支持它们,但我仍然有两个理由喜欢使用Bluebird和lodash之类的东西: 1.即使您可以控制服务器的环境和节点版本,但无法控制访问您的网站的浏览器,所以如果您有使用这些功能的前端代码,即使Safari有时也不支持它们。这些库可以为你填充,所以你不必担心它。 2.像这样的实用函数库可以省去我的打字工作,而且很容易理解他们在做什么。 – Griffin

0

,因为你在里面超时匿名函数返回差异。如果你想等待promise链,你必须从getDiff返回Promise实例,就像你之前在getSum中做的那样。

function getDiff(n1,n2){ 
    var diff = n1-n2; 
    return new Promise(function(resolve, reject) { 
     setTimeout(function(){ 
      console.log("value of diff--- ", diff) 
      resolve(diff); 
     }, 2000); 
    }); 
}