承诺拒绝会发出警告,即使稍后被捕获

时间:2018-08-26 19:17:17

标签: javascript node.js typescript promise

示例

class Foo {
    private pro = new Promise(() => {
                      throw new Error();
                  });

    public usePro() {
        return this.pro.then(() => {});
    }
}

let foo = new Foo();
setTimeout(() => {
    foo.usePro().then(() => {
        console.log("end.");
    }).catch(() => {
        console.log("error.");
    })
}, 1000);

我知道javascript无法在运行时知道某个人以后会捕获该错误,那么在这种情况下我应该怎么办?

控制台

(node:39166) UnhandledPromiseRejectionWarning: error
(node:39166) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:39166) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
error.
(node:39166) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)

3 个答案:

答案 0 :(得分:1)

无论在哪里使用Promise,都应捕获错误,即使该Promise在以后被其他东西返回(并捕获)了。一种选择是将>>> a = [[randint(0, 10) for _ in range(3)] for _ in range(1000)] >>> b = [[randint(0, 10) for _ in range(3)] for _ in range(1000)] >>> %timeit [x for x in b if x not in a] 10 loops, best of 3: 82.5 ms per loop >>> %timeit set(map(tuple, b)) - set(map(tuple, a)) 1000 loops, best of 3: 1.16 ms per loop >>> %timeit list(map(list, set(map(tuple, b)) - set(map(tuple, a)))) 1000 loops, best of 3: 1.43 ms per loop 对象或this.proValue对象分配给resolved,这取决于原始的Promise决定还是拒绝。然后,在调用rejected时,检查usePro并返回this.proValuePromise.resolve(resolved)。使用标准Javascript,因此可以在可运行的代码段中显示:

Promise.reject(rejected)

如果您想在class Foo { constructor() { this.pro = new Promise(() => { throw new Error('Problem!'); }) .then((resolved) => { this.proValue = { resolved }; }) .catch((rejected) => { this.proValue = { rejected }; }); } usePro() { const { resolved, rejected } = this.proValue; if (resolved) return Promise.resolve(resolved); else if (rejected) return Promise.reject(rejected); } } const foo = new Foo(); setTimeout(() => { foo.usePro().then(() => { console.log("end."); }).catch((e) => { console.log("error caught. " + e); }) }, 1000);的内部usePro已解决(或拒绝)之前致电Foo,请在Promise之前进行呼叫。 }被调用,构造并返回usePro的{​​{1}}解析(或拒绝)后解析的Promise。不幸的是,所需的代码稍微复杂一些:

this.pro

答案 1 :(得分:1)

CertainPerformance的回答很好。

让我在Node.js中添加一个内容,也可以在unhandledRejection上添加一个process侦听器:

process.on('unhandledRejection', reason => {
    console.error({Error:reason})
    process.exit(1);
});

答案 2 :(得分:0)

您可以使用Promise.all延迟解决:

  const delay = ms => new Promise(res => setTimeout(res, ms));

  Promise.all([
      foo.usePro(),
      delay(1000)
  ]).then(() => { 
     console.log("end.");
  }).catch(() => { 
     console.log("error."); 
  });

那样,.catch被直接附加,但是在延迟之后执行then回调。