【问题标题】:How to chain promises如何链接承诺
【发布时间】:2019-05-24 02:58:45
【问题描述】:

在这个简化的示例中,当第一个承诺得到解决时,我将调用三个函数。

var test = new Promise(function (res, err) { setTimeout(res, 3000) })

test.then( () => { console.log("A") });
test.then( () => { 
    return new Promise(function(res, err) { 
        setTimeout(()=> { console.log("C"); 
        res() }, 3000) 
    }); 
});

test.then( () => { console.log("B") });

预期的输出是A B C

假设我想调用第三个.then 来控制台B 只有当第二个承诺得到解决。

如果我尝试将第二个 Promise (myProm) 存储在全局中并在其上附加一个 .then 函数,我将(合理地)得到一个 TypeError,因为在编译时 myProm 仍未定义。

var test = new Promise(function (res, err) { setTimeout(res, 3000) })
var myProm;

test.then( () => { console.log("A") });
test.then( () => { 
    myProm = new Promise(function(res, err) { 
        setTimeout(()=> { console.log("C"); 
        res() }, 3000) 
    })
    return myProm;
});

myProm.then( () => { console.log("B") });

我该如何进行?将两个 Promise 链接在一起的最佳方法是什么,以便在我们执行下一个 then 之前,需要解决从一个 .then 返回的 Promise obj。

在这种情况下,我希望得到的输出是A C B

【问题讨论】:

  • test.then(...).then(...)…?!

标签: javascript promise


【解决方案1】:

then 返回一个承诺,当指定的函数运行并且它返回的值已经解决时,该承诺会解决(这有点过于简单,但对于这里的任务来说已经足够了)。

因此,在then 的结果上链接承诺。只需添加另一个.then

var test = new Promise(function (res, err) { setTimeout(res, 3000) })

test.then( () => { console.log("A") });
test
    .then( () => { 
        return new Promise(function(res, err) { 
            setTimeout(()=> { console.log("C"); res() }, 3000);
        });
    })
    .then( () => { console.log("B") });

【讨论】:

  • ...不要忘记then回调中的return关键字。
  • @Bergi 如果你错过了 return 语句会发生什么,它会隐式返回 undefined 吗?
  • @leonardofed 是的,但是它不会等待你在回调中创建的承诺,而只是等待undefined
  • @Bergi 好的,这意味着承诺将立即被解析为未定义,它会破坏我的代码的异步性。对吗?
  • @leonardofed 是的,例如,如果您从我上面代码的第 6 行中删除了return,那么B 将在C 之前记录。
【解决方案2】:

每次调用.then 时,您都会创建一个 Promise,当.then 返回的Promise 解析时,该Promise 就会解析。您应该将包含myProm.then 的结果分配给一个变量,然后对该变量调用.then

var test = new Promise(function (res, err) { setTimeout(res, 500) })
var myProm;

test.then( () => { console.log("A") })
  .then( () => { 
      myProm = new Promise(function(res, err) { 
          setTimeout(()=> { console.log("C"); 
          res() }, 500) 
      })
      return myProm;
  })
  .then( () => { console.log("B") });

大多数时候在使用Promises 时,您应该像这样链接.thens。只有在 prom 解析后,当您想要初始化两个完全独立的异步操作时才执行 prom.then(...) ... prom.then(...)

【讨论】:

  • > 每次调用 .then 时,都会创建一个新的 Promise,它会在 .then 返回的 Promise 解析时解析。这是一个隐含的承诺吗?你能指出规格吗?
  • 这是一个成熟的Promise,一点也不含蓄。请参阅 MDN's notes 链接
猜你喜欢
  • 1970-01-01
  • 2015-04-15
  • 2023-01-27
  • 2015-01-21
  • 2016-01-17
  • 1970-01-01
  • 1970-01-01
  • 2017-01-14
  • 1970-01-01
相关资源
最近更新 更多