繁体   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