我一直试图让Promise.all在Promise列表中没有成功,所以相反只尝试了一个承诺的数组,我得到同样的问题:
let tasks = [];
tasks.push(function(resolve, reject){
superagent
.post(URL_ROOT + url_path)
.send(data)
.end(function(err, res){
if(err)
reject(err);
assert.equal(res.status, status.UNAUTHORIZED); //401
console.log('Promise completed successfully');
resolve();
});
});
Promise.all([
new Promise(tasks[0])
]).then( function(){
console.log("Done");
done();
})
.catch( function(reason){
throw new Error(reason);
});
“承诺成功完成”打印得很好,但它只是挂起,“完成”永远不会打印。
非常感谢任何帮助。
答案 0 :(得分:5)
查看节点处理程序:
.end(function(err, res){
if(err)
reject(err);
assert.equal(res.status, status.UNAUTHORIZED); //401
console.log('Promise completed successfully');
resolve();
});
如果出现错误(并且断言成功),这将调用reject
和resolve
。我怀疑你的情况,所以承诺被拒绝(因为在解决之前调用了拒绝),代码继续并打印Promise completed successfully
。
之后,promise链会进入拒绝处理程序:
.catch( function(reason){
throw new Error(reason);
});
但是这段代码没有做任何事情,因为投入一个承诺延续将转化为对所产生的承诺的拒绝,这个承诺在这里被遗忘。
尝试以下方法验证我的理论,看看它是否记录:
.catch( function(reason){
console.log("Promise rejected");
throw new Error(reason);
});
要解决此问题,您需要做的就是重新构建代码:
.end(function(err, res){
if(err) {
reject(err);
} else {
resolve();
assert.equal(res.status, status.UNAUTHORIZED); //401
console.log('Promise completed successfully');
}
});
因此,您已将异步任务转换为正确的promise(可能还必须处理.on("error", reason => reject(reason))
),并在catch子句中放入错误处理程序。
如果您仍想将错误传递给全局错误处理程序,那么您最好能够在setTimeout
中执行此操作,因此promise回调无法捕获并转换错误:
.catch( function(reason) {
setTimeout(() => {
throw new Error(reason);
}, 0);
});