我怎么知道哪些处理程序在承诺中抛出错误?

假设我有一个承诺如下:

p.then(Task1) .then(Task2) .then(Task3) .catch(errorHandler); 

Task2遇到错误时,如何知道错误是从Task2捕获的

大家! 我自己研究过演示代码。

我希望大家可以回顾一下我的答案,不pipe好不好。


介绍:

它显示了如何跟踪每个处理程序中的promise,使用自定义的error handling程序来捕获错误。 了解承诺的工作stream程。

您可以复制以下演示代码并粘贴到您的node.js中 。 根据这个例子和日志消息,开发者学习诺言是有好处的。


使用的承诺模块如下:

  • 知更鸟

演示代码如下:

 var Promise = require('bluebird'); // You can input any argument in this function to test workflow of promise function testPromise(input) { let promise = Promise.resolve(input); promise .then(makeTask('Task1')) .then(makeTask('Task2')) .then(makeTask('Task3')) .catch(makeErrorPredicate('Task1'), taskLog('Task1')) .catch(makeErrorPredicate('Task2'), taskLog('Task2')) .catch(makeErrorPredicate('Task3'), taskLog('Task3')) } // define task handler functions function makeTask(task) { return function task1Handler(input) { if (input === task) { throw new Error(task) } return input } } // custom error that it checks error message function makeErrorPredicate(msg) { return function taskError(err) { var result = err.message === msg; console.log(msg + ': ' + result) return result; } } // hint the error when the error has matched function taskLog(msg) { return function thelog(err) { console.log('It\'s ' + msg) } } 

这个例子:

 >testPromise('Task1') Task1: true It's Task1 >testPromise('Task2') Task1: false Task2: true It's Task2 >testPromise('Task3') Task1: false Task2: false Task3: true It's Task3 

从上面的例子我们可以知道:

input是'Task1'时,路线是:

firstHandler – > firstCatcher

input是'Task2'时,路线是:

firstHandler – > secondHandler – > firstCatcher – > secondCather

input是“Task3”时,路线是:

firstHandler – > secondHandler – > thirdHandler – > firstCatcher – > secondCatcher – > thirdCatcher

所以,从上面的结果我们知道,我们可以理解如何工作的承诺。


如果大家都对这个答案感到满意,请告诉我,谢谢。

由于承诺链不能保存这些信息,因此您需要将其存储在某个地方。 两种解决scheme

装饰错误:

 p.then(Task1) .then(function() { try { Task2(); } catch (e) { e.isFromTask2 = true; throw e; } }) .then(Task3) .catch(errorHandler); // now you can check err.isFromTask2 

使用承诺链的范围:

 { let isFromTask2 = false; p.then(Task1) .then(function() { try { Task2(); } catch (e) { isFromTask2 = true; throw e; } }) .then(Task3) .catch(errorHandler); // now you can check isFromTask2 } 

大多数浏览器都支持error.stack属性,一些现代浏览器甚至支持asynchronous调用堆栈:

 let a = () => Promise.resolve(); let b = () => Promise.reject(new Error("Fail")); let c = () => Promise.resolve(); Promise.resolve().then(a).then(b).then(c).catch(e => console.log(e.stack)); 

为了知道在所有浏览器中来自Task2的最后一个catch中的(asynchronous)错误,你可以抓住它,给它加上标签并重新抛出它:

 var tag = (e, name) => (e.isFrom = name, Promise.reject(e)); p.then(Task1) .then(Task2) .catch(e => tag(e, "Task2")) .then(Task3) .catch(errorHandler); 

不幸的是,这将会从Task1p捕获错误,所以你还需要一个“绕过”的方法:

 p.then(Task1) .then(result => Task2(result).catch(e => tag(e, "Task2"))) .then(Task3) .catch(errorHandler); 

这使Task1或更早的任何错误“绕过”(即绕过)我们的Task1的捕获。

这是有效的,因为我们把catch放在了.then的成功callback里面。 每一个.then都有一个隐含的第二个参数,它是一个error handling程序,就像.catch ,除了它不捕获相应的成功callback,在这种情况下, Task2和我们的catch,只有链上的前一个错误(即Task1或任何先前的步骤)。

省略错误callback意味着“通过这个不变”。 即与e => Promise.reject(e)

 let tag = (e, name) => (e.isFrom = name, Promise.reject(e)); let a = () => Promise.resolve(); let b = () => Promise.reject(new Error("Fail")); let c = () => Promise.resolve(); let x = () => null.f(); let foo = failFirstStep => Promise.resolve() .then(failFirstStep? x : a) .then(() => b().catch(e => tag(e, "b"))) .then(c) .catch(e => console.log((e.isFrom || "something else") + " failed")); foo(false).then(() => foo(true)); 

你可以这样做;

 Promise.resolve(21).then(v => v*2) .then(v => { try { throw new Error(v + " is immutable") } // assuming that your code results an error catch(err){ return Promise.reject({message: "2nd then stage threw an error", err:err}) } }) .then(v => v) .catch(err => console.log(err.message, "\n",err.err.message));