承诺链:在创建Promise时添加错误处理程序与通过promise添加变量

时间:2018-07-15 15:52:57

标签: javascript node.js promise

function getPromise() {
    return new Promise((resolve, reject) => {
        setTimeout(reject, 2000, new Error('fail'));
    });
}

const promise1 = getPromise();
promise1.catch(() => {
    // NOP
});

promise1
    .then(() => console.log('then promise1'))
    .catch(() => console.error('catch promise1'));

const promise2 = getPromise().catch(() => {
    // NOP
});

promise2
    .then(() => console.log('then promise2'))
    .catch(() => console.error('catch promise2'));

输出

catch promise1
then promise2

说明

此处promise2promise1的处理方式有所不同。 promise1将被拒绝,并显示“失败”错误,而promise2将被undefined解决。

我的环境

Ubuntu 14.04,Node.js 10.1.0

问题

我认为这种行为并不明显。为什么代码以这种方式工作?

2 个答案:

答案 0 :(得分:2)

Catch返回新的承诺:

let orig = Promise.reject("fail")
let p = orig.catch(console.log)

console.log("is p the same as orig? ", p === orig)

p.then(() => console.log('p is a promise?', p instanceof Promise))

因此,当您致电

 const promise2 = getPromise().catch(() => { //..})

,并将值分配给promise2返回的全新承诺catch。在第一种情况下,您在两个语句中都使用了口语promise1

要使第一个语句像第二个语句一样工作,您需要执行以下操作:

function getPromise() {
    return new Promise((resolve, reject) => {
        setTimeout(reject, 2000, new Error('fail'));
    });
}

let promise1 = getPromise();

// reassign the value of promise1
promise1 = promise1.catch(() => {
    // NOP
});

promise1
    .then(() => console.log('then promise1'))
    .catch(() => console.error('catch promise1'));
这也等同于只做:

promise1
  .catch(() => {/* noop */ })
  .then(() => console.log('then promise1'))
  .catch(() => console.error('catch promise1'));

此外,如果您要确保错误是沿着链条传递的,则始终可以从catch返回被拒绝的承诺:

let promise1 = getPromise().catch((e) => {
    return Promise.reject(e)
});

答案 1 :(得分:2)

因为您将第二个链接而不是拒绝承诺,而是链接到catch返回的承诺,这将解决您从catch处理程序返回的任何内容。

 Promise(promise1)
  -❎-> catch
  -✔-> then -❎- > catch
  -❎-----------------^

Promise
  -❎-> catch(promise2)
           -✔-> then -❎-> catch
           -❎-----------------^
  -✔------------^

在第一种情况下,promise被拒绝,因此它将输入直接分配给它的catch,并且它将跳过then,直接进入链接的catch。在第二种情况下,promise将被拒绝,catch将被执行,但是它似乎可以处理错误,因此将调用链接的then。如果您不希望这样做,则catch必须重新throw错误,然后then将被跳过,并且还将输入链接的catch