返回承诺与返回承诺内未定义之间的区别

Difference between returning a promise vs returning undefined inside a promise

本文关键字:返回 承诺 区别 之间 未定义      更新时间:2023-09-26

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

假设我们有这个:

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

对:

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

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

如果不从then回调返回值,则实际上返回undefined 。下一个then回调将立即运行,并将undefined视为解析值。

如果从then回调返回承诺,则第二个then回调将等待该承诺(间接,但这并不重要(,当该承诺被解析时,将从该承诺中获取解析值。

(这在 Promises/A+ 规范中的 then 规范中有所涵盖,但略有遗漏 ——它没有明确提到如果 onFulfilled 不返回任何内容会发生什么,但在 JavaScript 中,调用函数总是给你一个结果值;如果函数没有显式返回某些内容,undefined是调用它的结果。JavaScript没有void方法的概念,例如C/C#/C++/Java。

你可以在 Babel's 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){
});

输出是(例如(:

0015: 另一个承诺[没有]得到420017: 另一个承诺2[没有]未定义0018: 全部完成0020: 另一个承诺[与]得到421021: 另一个承诺2[与]得到841032:全部完成

请注意退货和退货之间的区别:

  • 如果没有anotherPromise2立即被调用(正如我们从经过的时间值中看到的那样(并收到undefined .

  • 有了anotherPromise2等待anotherPromise的分辨率发生,然后接收84(anotherPromise的分辨率值(

区别在于这件事的时机。

在示例 1 中,save承诺已满,anotherPromise1将被调用,并且由于没有返回任何承诺,因此将立即调用anotherPromise2

如果返回 anotherPromise1 函数的承诺,则在解决anotherPromise1后,将发生anotherPromise的调用。

所以示例 1:anotherPromise1anotherPromise2 将同时拍摄而示例 2:anotherPromise2将等待anotherPromise1得到解决