究竟是什么.then()处理传入的函数?

时间:2014-07-02 17:09:56

标签: javascript promise bluebird

根据承诺A +规范,

  

2.2.2.1如果onFulfilled是一个函数,则必须在promise完成后调用它,并将promise的值作为其第一个参数。

但是,如果承诺传入.then()会怎样?

现在我们有了这段代码:

var Promise = require('bluebird');
var func1 = function() {
    return new Promise(function(resolve, reject) {
        resolve('hello'); 
    }); 
}

var wrapper = function() {
    return func1();
}

var api = function() {
    return wrapper()
            .then(wrapper());
}

api().then(function(msg) {
    console.log(msg);
});

为什么'你好'打印出来?

在api函数中,wrapper()通过func1()被评估为一个承诺,并被传入.then()。现在,根据引用的规范,这个承诺行为'onFulfilled'功能。但是,规范说onFulfilled(在这种情况下返回的promise)期望传入的参数作为前一个promise调用.then()的。但是,如何将价值传递给承诺呢?

我不善于解释事情。所以,如果你感到困惑,你能解释为什么打印“你好”吗?怎么样?

1 个答案:

答案 0 :(得分:3)

  

但是如何将价值传递给承诺呢?

它不能和您引用的规范部分应该已经告诉过您:

  

如果onFulfilled是函数[...]

承诺不是功能! (通常,如果是,它会像一个函数,而不是一个承诺)。

所以致电.then basically doesn't do anything

  

2.2.7.3如果onFulfilled不是函数且promise1已满足,则必须使用与promise2相同的值来完成promise1

promise1已完成

"hello",因此promise2也符合要求。

wrapper()/*promise 1*/.then(wrapper())/*promise 2*/.then(function(msg) {
    console.log(msg);
});

基本上是

wrapper()/*promise 1*/.then(function(msg) {
    console.log(msg);
});

这就是打印"hello"的原因。


现在,如果你通过了wrapper,那么就是一个函数,即wrapper().then(wrapper).then(...),它与

相同
wrapper()/*a*/.then(function foo(result) {
    return func1(); /*b*/
})/*c*/.then(function(msg) {
    // ...
});

然后foo将从第一个承诺(a)获得结果(根据您引用的部分)。由于onFulfilled函数返回一个promise本身(b),.thenc)返回的promise将使用该内部promise({{1}的值来解析})(恰好产生与第一个初始承诺(b)相同的值。)

section 2.3中对此进行了描述,其中ax返回的值。

  
      
  • 如果x是承诺,则采用其状态:   
        
    • 如果x处于待处理状态,则承诺必须保持等待状态,直到x完成或被拒绝。
    •   
    • 如果/当x满足时,用相同的值履行承诺。
    •   
    • 如果/当x被拒绝时,请以同样的理由拒绝承诺。
    •   
  •