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

Javascript 返回承诺与返回未定义的承诺之间的区别,javascript,node.js,promise,es6-promise,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){

我不太清楚这两种常见情况之间的区别

假设我们有:

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
回调返回一个承诺,那么第二个
then
回调将等待该承诺(间接地,但这并不重要),当该承诺得到解决时,将从该承诺中获取解决值

(这在中的
then
规范中有介绍,但略作省略-它没有明确提到如果
onimplemented
不返回任何内容会发生什么情况,但在JavaScript中,调用函数总是会给您一个结果值;如果函数没有显式返回某个内容,
未定义的
则不会JavaScript没有
void
方法a'la C/C#/C++/Java的概念

您可以在此脚本中看到它:

let start=Date.now();
函数(){
让rv=String(Date.now()-start);
而(rv长度<4){
rv=“0”+rv;
}
返回rv;
}
函数另一个承诺(类型,val){
log(`${appeased()}:另一个承诺[${type}]得到了${val}`);
返回新承诺(解决=>{
setTimeout(()=>{resolve(val*2);},1000);
});
}
功能其他承诺2(类型,val){
log(`${appeased()}:anotherPromise2[${type}]获得${val}`);
返回新承诺(解决=>{
setTimeout(()=>{resolve(val*3);},10);
});
}
让用户={
保存:()=>{
返回新承诺(解决=>{
设置超时(()=>{
决心(42);
}, 10);
});
}
}
//一无所获
user.save().then(函数(val){
另一个承诺(“无”,val);
}).then(功能(val){
另一份承诺书2(“无”,val);
}).然后(函数(){
log(`${appeased()}:All done`);
}).catch(函数(err){
});
user.save().then(函数(val){
返回另一个承诺(“带”,val);
}).then(功能(val){
归还另一份承诺书2(“连同”,val);
}).然后(函数(){
log(`${appeased()}:All done`);
}).catch(函数(err){
});
输出为(例如):

0015:另一个承诺[没有]得到了42 0017:另一个承诺2[无]未定义 0018:全部完成 0020:另一个承诺得到了42 1021:另一个允诺人得到了84分 1032:全部完成 请注意无退货和有退货的区别:

  • 如果没有,则会立即调用另一个Promise2
(我们可以从经过的时间值中看到),并收到未定义的

  • 使用,
    anotherPromise2
    等待
    另一个承诺的解决方案,然后收到
    84
    另一个承诺的解决方案值)


  • 区别在于这件事的时机

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

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

    因此,示例1:
    另一个允诺者1
    另一个允诺者2
    将同时拍摄 例2:
    anotherPromise2
    将等待
    anotherPromise1

    得到解决,看看它在哪里提供了一些关于如何使用承诺的场景。搜索解决这个难题,你会发现一个部分,作者直观地显示了链接承诺的几种方式之间的时间差异(包括你的两个例子)。你不是“在”一个承诺内。你是在一个函数内(希望是)返回一个承诺。”所以例子1:
    另一个承诺1
    另一个承诺1
    将同时被拍摄“我想你的意思是”
    另一个承诺
    另一个承诺2
    (OP的名字不一致)不,它们不是同时发生的,它们将依次完成,
    anotherPromise2
    ,然后
    anotherPromise2
    ,其中
    anotherPromise2
    接收包含
    anotherPromise2
    已完成的
    回调的返回值。您在回答的开头说得对,只是没有在总结中最后。另外,在分辨率值方面有重要的区别,而不仅仅是时间。
    
    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