Javascript 蓝鸟:如何绑定承诺,以便我可以在.catch中自定义行为,然后允许错误继续级联?
注意-请参阅下面的更新 我想要一个在第一个任务和其他辅助任务之间的执行之间具有依赖关系的流,但是其他辅助任务都可以并发运行。 我想写一个干净的流,这将使它容易处理错误,我已经尝试了几种变化,但不能得到正确的 以下是我将要使用的内容,无论我如何编写它:Javascript 蓝鸟:如何绑定承诺,以便我可以在.catch中自定义行为,然后允许错误继续级联?,javascript,promise,bluebird,Javascript,Promise,Bluebird,注意-请参阅下面的更新 我想要一个在第一个任务和其他辅助任务之间的执行之间具有依赖关系的流,但是其他辅助任务都可以并发运行。 我想写一个干净的流,这将使它容易处理错误,我已经尝试了几种变化,但不能得到正确的 以下是我将要使用的内容,无论我如何编写它: var primaryAsyncTask = {...}; //single 'task' which has an execution function var secondaryAsyncTasks = [{...}]; //array of
var primaryAsyncTask = {...}; //single 'task' which has an execution function
var secondaryAsyncTasks = [{...}]; //array of tasks with same format as above
function promisifyTask(task){ .... }; //returns a promise which executes the task and appends the resolve/reject functions as the last arguments to the task execution function
下面是我目前尝试的两个选项:
function onTaskFail(reason){
//do something to save info from reason onto this = task, since it was bound before the catch
}
function promisifyTask(task){
return new Promise(function(resolve, reject) {
task.execute.apply(null, task.args.concat([resolve, reject]));
});
}
function promisifyTaskAndCatch(task){
return promisifyTask(task).bind(task).catch(onTaskFail)
}
//and then when executing:
promisifyTask(primaryAsyncTask)
.then(function (){
return Promise.settle(secondaryAsyncTasks.map(function (task) {
return promisifyTaskAndCatch(task);
}));
})
.then(function onSuccess(){...})
.catch(function onFail(){...})
function promisifyTask(task) {
var promise = new Promise(function (resolve, reject) {
task.execute.apply(null, task.args.concat([resolve, reject]));
});
promise.bind(task).catch(onTaskFail);
return promise;
}
现在语法是一致的,错误层叠通过,我也得到了我的错误报告
现在唯一的问题是,我不能保证任务的内部捕获会在外部最终捕获之前发生(onFail位于链的末尾),因为这是异步的
有没有办法回报被抓住的承诺,但仍然失败?我是否可以在不重复.catch中的错误的情况下执行此操作
现在唯一的问题是,我不能保证任务的内部捕获会在外部最终捕获之前发生(onFail位于链的末尾),因为这是异步的
实际上您确实有,因为首先调用了.catch(onTaskFail)
,所以onTaskFail
将在最后一个之前执行。但您是对的,如果最终捕获取决于onTaskFail
所做的事情,那么实际返回对该结果的承诺将更加清晰
有没有办法回报被抓住的承诺,但仍然失败
我认为重新抛出ingreason
将是最好的选择
或者您甚至不让它们失败,而是使用并检查任务对象的结果,而不是使用及其PromiseInspection
值。正如您所说,原因保存在任务上,最一致的流程是返回任务对象:
function onTaskFail(reason){
this.error = reason; // or so
return this;
}
runTask(primaryAsyncTask).then(function(primResult) {
return Promise.all(secondaryAsyncTasks.map(function (task) {
return runTask(task).bind(task).catch(onTaskFail);
}));
}).then(function(taskResults) {
// test for errors in the secondary results
// and throw them if you want the global onFail
// else do onSuccess()
}).catch(onFail);
我是否可以在不重复.catch中的错误的情况下执行此操作
是的,您还可以返回被拒绝的承诺。这可能是一个承诺。拒绝(原因)
,但更简单的可能是返回已经存在的承诺(尽管当前不在onTaskFail
的范围内)。但是,可以在此处使用:
…
return promise.bind(task).catch(onTaskFail).return(promise);
我建议您将函数命名为runTask
。“Promisification”是另一回事。你是对的——promisifiedTask的功能实际上类似于“promisifiedTask”。Promisification将返回promisifyTask而不运行它…嗯,还有一件事:不承诺。结算返回一个始终已解决的承诺,这样您的全局onFail
处理程序将永远看不到被拒绝的次要任务的原因?非常有趣-从捕获中返回任务。我喜欢。关于Promise.all-如果其中任何一个失败,它将立即拒绝,但我想等待所有这些都完成,这就是为什么我使用结算。。。虽然它似乎总是会回报一个兑现的承诺。也许我可以这样做:runTask().then(runAlllTasks//returns promise.settle)。then(function(reasons){return promise.all(reasons)})。then(onSuccess)。catch(onFail)但是当你.catch()
所有错误时,没有一个会失败……如果我使用promise.all对已解决的结果进行处理,如果任何失败,它总是会到达catch,这很好。我将把它作为一个更新发布。我不知道它是否是有意的,但是如果你遵循蓝鸟的来源,它是合乎逻辑的。请参阅:遵循init(这是promiseInspection.all)-promiseInspection不会被强制转换为promiseInspection,并最终在值的直接扫描中输入PromiseArray$\u SettlePromission,其中它询问promiseInspection对象所具有的value.isCompleted()和value.isRejected()。这看起来几乎是故意的,因为在检查中达到这一点的唯一方法似乎是演员是否返回了原始PromiseInspection看起来我在测试这一点时使用了旧版本的bluebird,因为在当前版本上,它不起作用。完成了。
…
return promise.bind(task).catch(onTaskFail).return(promise);