javascript - 在原生 Javascript 中链接 Promise

标签 javascript ecmascript-6 es6-promise

我想将 3 个 promises 链接在一起,但是关于 resolvereject 功能我无法弄清楚一些行为。我简化了我的代码以提出问题:

function testP(num) {
  return new Promise((resolve, reject) => {
    console.log('Do Work', num);
    reject(num);
  });
}

function testPromises() {
  return new Promise((resolve, reject) => {
      testP(1)
        .then(testP(2))
        .then(testP(3))
        .then(resolve)
        .catch(reject);
  });
};

const theTest = testPromises().then(()=>{
    console.log("all done");
}).catch(err => {
    console.log("ERR", err);
});

我在输出中看到的是:

Do Work 1
Do Work 2
Do Work 3
ERR 1

如果第一个 promise 立即命中 reject,为什么代码会到达 Do Work 2Do Work 3?我的理解是 then 函数在执行之前等待 resolvereject 的 promise 。

最佳答案

因为当你这样做

.then(testP(2))

你立即无条件地调用testP,传入2,然后将它的返回值传入.then,和一样>foo(bar()) 调用 bar 并将其返回值传递给 foo

这段代码:

  testP(1)
    .then(testP(2))
    .then(testP(3))
    .then(resolve)
    .catch(reject);

是这样计算的(省略了一些小细节):

  • 用值 1 调用 testP 并将结果值记住为 p1
  • 用值2调用testP
  • 使用该调用的结果调用 p1.then 并将结果值记为 P2
  • 用值 3 调用 testP
  • 使用该调用的结果调用 p2.then 并将结果值记住为 p3
  • 使用值resolve调用p3.then并将结果记为p4
  • 使用值reject调用p4.catch
  • 从第一次调用 testP 开始调用 reject 函数,值为 1
  • 使用值 1 从 testPromises 调用 reject

如果您希望 testP 等到第一个被解决,您不调用它,而是传递对它的引用:

.then(testP)

如果你想让它有一个参数,使用bind:

.then(testP.bind(null, 2))

或内联函数:

.then(function() {
    return testP(2);
 })

示例 (需要带有 Promise 的浏览器):

function testP(num) {
  return new Promise((resolve, reject) => {
    console.log('Do Work', num);
    reject(num);
  });
}

function testPromises() {
  return new Promise((resolve, reject) => {
      testP(1)
        .then(testP.bind(null, 2))
        .then(testP.bind(null, 3))
        .then(resolve)
        .catch(reject);
  });
};

const theTest = testPromises().then(()=>{
    console.log("all done");
}).catch(err => {
    console.log("ERR", err);
});

关于javascript - 在原生 Javascript 中链接 Promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38003182/

相关文章:

javascript - 对象到数组的转换

javascript - 将数组和键合并在一起以进行表输出

node.js - 在非回调函数 : "interesting" results in node. 上调用 promisify() 为什么?

javascript - ES6 Javascript Promise - 在调用 .then() 之后执行

javascript - 由 JavaScript 生成时 SVG textPath 不渲染

javascript - 将所有 href 值更改为数组值理论与实践

javascript - Plupload - 事件未触发

javascript - Do/While 循环结合 setTimeout 创建无限循环

javascript - IntersectionObserver 不适用于长部分 JS 的小屏幕

javascript - promise 未决,已履行不返回