在promise

时间:2016-02-16 08:10:01

标签: javascript node.js promise es6-promise

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

说我们有这个:

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){

});

我知道这有所不同,但究竟是怎么回事?

2 个答案:

答案 0 :(得分:9)

如果您未从then回调中返回值,则表示您实际返回undefined。下一个then回调将立即生效,并将undefined视为分辨率值。

如果从then回调中返回一个承诺,则第二个then回调会等待该承诺(间接地,但这并不重要),并且当该承诺得到解决时,获取该承诺的分辨率值。

(这由Promises/A+ spec中的then规范涵盖,但略有遗漏 - 它没有明确提及如果onFulfilled没有返回任何内容会发生什么,但在JavaScript中,调用函数总是给出结果值;如果函数没有显式返回某些内容,undefined就是调用它的结果.JavaScript没有概念void方法a'la C / C#/ C ++ / Java。)

您可以在此脚本live copy on 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: 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的分辨率发生,然后获得84anotherPromise分辨率值)

答案 1 :(得分:2)

不同之处在于此事的时间安排。

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

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

示例1:anotherPromise1anotherPromise2将同时拍摄 虽然示例2:anotherPromise2将等待anotherPromise1被解析