簡體   English   中英

承諾.then(async())與.then(function(){return async()})

[英]Promises .then(async()) versus .then(function(){return async()})

我試圖弄清楚為什么發生以下行為,以及可能帶來的好處。 使用bluebird作為promise實現。

printValue = function (value){
   return new Promise(function(resolve, reject){
      console.log(value);
      resolve(value)
   });
}

describe.only('promises', function(){
   it('prints values with then', function(done){
      printValue(1)
      .then(printValue(2))
      .then(function(value){
         console.log('then value: ', value);
      })
      .then(done())
   });

   it('prints values with return', function(done){
      printValue(1)
      .then(function(){
         return printValue(2);
      })
      .then(function(value){
         console.log('return value: ', value);
      })
      .then(done())
   });

});

輸出:

1
2
then value: 1

1
2
return value: 2

當第二個測試從第二個承諾中獲得價值時,為什么第一個測試保留原始承諾中的價值? 這是否意味着僅當您不將參數傳遞給函數時,才使用.then(async()) 還是還有一種使用上述語法傳遞參數的方法?

這不容易看到。

在第一部分中,您具有:

printValue(1)
      .then(printValue(2))
      .then(function(value){
         console.log('then value: ', value);
      })

您會看到,您實際上是在調用printValue(2)並且在調用它時會立即執行,它不會等待先前的函數被調用並且它們的promise將被解析。 盡管printValue返回一個Promise ,但.then期望一個函數在調用時返回一個Promise (或者只是一個返回值的函數)。

因此,在.then(printValue(2)).then接收一個非函數值,它只是將其忽略,然后轉到鏈中的下一個函數。

您可以嘗試例如查看以下內容:

printValue(1)
    .then("hello!")
    .then(function (val) {
        console.log("got " + val)
    });

因此,它實際上與您擁有的東西相同,只是有一個返回值的函數,這里我們只是將其替換為值!

您也可以嘗試以下操作:

var printValue = function (value){
    return new Promise(function(resolve, reject){
        console.log("called " , value)
        setTimeout(function () {
            console.log("resolving ", value);
            resolve(value)
        }, value*1000);
    });
}

您會在這里看到:

printValue(1)
        .then(printValue(2))
        .then(function (val) {
            console.log("got " + val)
        });

printValue(1)printValue(2)同時執行。 一秒鍾后, printValue(1)將解析並got 1

希望我能幫上忙。
為什么第一個測試保留原始承諾的價值?
-因為它是util解析的,所以會找到一個可以解析的函數。
-為了使承諾得到解決,它需要找到一種正確的方法來傳遞已解決的值。
要解決您的第一種情況,您需要執行以下操作:

printValue(1)
  .then(printValue)      
  .then(function(value){
     console.log('then value: ', value);
  })

因此,當第一個printValue(原始)得到解析時,它將把值傳遞給第二個printValue。
傳遞更多參數的方法是使用咖喱。 采取以下示例(使用ramda ):

'use strict';
const Promise = require('bluebird');
const R = require('ramda');

const printValue = R.curry(function (value){
   return new Promise(function(resolve, reject){
      console.log(value);
      resolve(value)
   });
});

const printSum = R.curry(function (val1, val2){
   return new Promise(function(resolve, reject){
       const r = val1 + val2;
      console.log(r);
      resolve(r)
   });
});     

printValue(1)
.then(printSum(R.__)(3))      
.then(function(value){
    console.log('then value: ', value);
})

因此,假設您想將printValue(original)的結果與另一個數字相加,將Curry與Ramda結合使用,您可以指定R .__ ,它將采用printValue的結果值,在這種情況下,您仍然可以傳遞和額外的參數3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM