我有一个Node.js应用程序。这个应用程序有一个启动进程的按钮。该过程中的步骤返回承诺。我试图将这些承诺联系起来。出于某种原因,我收到了UnhandledPromiseRejectionWarning
。但是,在我看来,我已经正确地设置了它。我的代码如下所示:
var myButton = document.getElementById('myButton');
if (myButton) {
console.log('here');
myButton.addEventListener('click', executeAction('0'));
}
function executeAction(input) {
let param1 = 'A';
let promise = new Promise(function(resolve, reject) {
try {
executeStep1()
.then(result => executeStep2(param1, result, input))
.then(result => function(result) {
console.log('All done');
resolve(result);
})
.catch(err => reject(err))
;
} catch (ex) {
reject(ex);
}
});
return promise;
}
function executeStep1() {
let promise = new Promise(function(resolve, reject) {
try {
setTimeout(function() {
resolve('[something]');
}, 3000);
} catch (ex) {
reject();
}
});
return promise;
}
function executeStep2(p1, p2, p3) {
let promise = new Promise(function(resolve, reject) {
try {
setTimeout(function() {
console.log('step 2 has executed');
resolve('awesome!')
}, 3000);
} catch (ex) {
reject(ex);
}
});
return promise;
}
我已确认executeStep2
功能已完成。我的基础是我可以看到"第2步已执行"在控制台窗口中。然而,令我惊讶的是,我从来没有看到"所有完成"打印在控制台窗口中。相反,我看到上面提到的UnhandledPromiseRejectionWarning
。我不明白这个结果的两个方面:
executeStep2
解决后,该功能是否应该执行?非常感谢你的帮助!
答案 0 :(得分:0)
executeStep1()
.then(result => executeStep2(param1, result, input))
.then(result => { // no function(result) here
console.log('All done');
resolve(result);
})
.catch(err => reject(err))
;
答案 1 :(得分:0)
当您调用使用promises的函数时会生成错误:
myButton.addEventListener('click', executeAction('0'));
你也需要在那里受到拒绝。
myButton.addEventListener('click', executeAction('0')
.catch((error) => console.log('ERROR', error));
拒绝被捕获在函数内部,但不在外部作用域中,因为executeAction('0')
返回一个promise,或者它会将它用作非异步函数,因此它创建一个promise然后返回等待承诺而不等待它被解决。这看起来像什么导致拒绝,并且由于上述原因也没有处理。
这将解决它:
function executeAction(input) {
let param1 = 'A';
return new Promise(function(resolve, reject) {
try {
executeStep1()
.then(result => executeStep2(param1, result, input))
.then(result => function(result) {
console.log('All done');
resolve(result);
})
.catch(err => reject(err))
;
} catch (ex) {
reject(ex);
}
});
}
您应该查看async / await。它可以显着清理此代码。
async function getSomething() {
try {
// throw 'Test error detected.'
return 'test'
}
catch (e) {
throw e
}
}
async function testing() {
try {
const sample = await getSomething()
return sample
} catch (e) {
throw e
}
}
testing()
.then((data) => console.log(data))
.catch((err) => console.log(err))
运行上面的示例,然后取消注释throw。使用此模式可获得最大胜利。应该将异常抛出到调用,显示,使用,渲染等函数的表面级别。函数应该简单地抛出错误。
这允许您使用错误处理中间件,高阶函数,侦听器,日志记录等