在promise中返回promise和返回undefined之间的区别

Ale*_*lls 6 javascript node.js promise es6-promise

我不太确定我理解这两种常见情况之间的区别.

说我们有这个:

user.save().then(function(val){
   anotherPromise1(val);
}).then(function(val){
   anotherPromise2(val);
}).catch(function(err){

});
Run Code Online (Sandbox Code Playgroud)

与:

user.save().then(function(val){
   return anotherPromise1(val);
}).then(function(val){
   return anotherPromise2(val);
}).catch(function(err){

});
Run Code Online (Sandbox Code Playgroud)

我知道这有所不同,但究竟如何呢?

T.J*_*der 10

如果你没有从then回调中返回一个值,那么你就会有效地返回undefined.下一个then回调将立即运行,并将其undefined视为分辨率值.

如果从then回调中返回一个promise ,则第二个then回调会等待该promise(间接,但这并不重要),并且当该promise被解析时,从该promise获得解析值.

(这是由覆盖then在说明书中承诺/ A +规格,但稍微疏忽-它并没有明确提及是否会发生什么onFulfilled不返回任何东西,但在JavaScript中,调用一个函数总是给你一个结果值;如果函数没有显式返回,undefined是调用它的结果void.JavaScript 没有方法的概念a'la C/C#/ C++/Java.)

你可以在这个脚本中看到它在Babel的REPL上的实时副本:

let start = Date.now();
function elapsed() {
  let rv = String(Date.now() - start);
  while (rv.length < 4) {
    rv = "0" + rv;
  }
  return rv;
}
function anotherPromise(type, val) {
  console.log(`${elapsed()}: anotherPromise[${type}] got ${val}`);
  return new Promise(resolve => {
    setTimeout(() => { resolve(val * 2); }, 1000);
  });
}
function anotherPromise2(type, val) {
  console.log(`${elapsed()}: anotherPromise2[${type}] got ${val}`);
  return new Promise(resolve => {
    setTimeout(() => { resolve(val * 3); }, 10);
  });
}
let user = {
  save: () => {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve(42);
      }, 10);
    });
  }
}

// Without return
user.save().then(function(val){
   anotherPromise("without", val);
}).then(function(val){
   anotherPromise2("without", val);
}).then(function() {
  console.log(`${elapsed()}: All done`);
}).catch(function(err){
});

user.save().then(function(val){
   return anotherPromise("with", val);
}).then(function(val){
   return anotherPromise2("with", val);
}).then(function() {
  console.log(`${elapsed()}: All done`);
}).catch(function(err){
});
Run Code Online (Sandbox Code Playgroud)

输出是(例如):

0015: anotherPromise[without] got 42
0017: anotherPromise2[without] got undefined
0018: All done
0020: anotherPromise[with] got 42
1021: anotherPromise2[with] got 84
1032: All done

注意之间的差异,而不返回并回归:

  • 没有,anotherPromise2立即调用(我们可以从经过的时间值看到)并收到undefined.

  • 随着,anotherPromise2等待anotherPromise分辨率发生,然后收到84(anotherPromise分辨率值)