Promises .then(async()) versus .then(function(){return async

Promises .then(async()) versus .then(function(){return async()})

本文关键字:then async return versus Promises function      更新时间:2023-09-26

我试图弄清楚为什么会发生以下行为,以及可能的好处是什么。使用bluebird作为承诺实现。

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),当你调用它时,它立即执行,它不等待前面的函数被调用和它们的承诺被解决。虽然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将被打印。

希望我能帮上忙。
为什么第一个测试保留了原始承诺的值?
-因为它会被解析,直到它找到一个可以解析它的函数。
-为了解决承诺,它需要找到一个合适的方式来传递解决的值。
要修复第一个场景,您需要这样做:
printValue(1)
  .then(printValue)      
  .then(function(value){
     console.log('then value: ', value);
  })

所以当第一个printValue(original)被解析时,它会将值传递给第二个printValue。
传递更多参数的方法是使用curry。以下面的例子为例(使用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