2017-09-25 129 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); 
    }); 
}