Bluebird Promise:嵌套函数中如何规避失控Promise警告?
问题分析
你遇到的这个场景确实挺棘手的:后台任务函数doBackgroundJob内部依赖Promise,但调用方完全不需要等待它完成,也不想为了抑制警告额外加return null——毕竟全局禁用这个警告太可惜,它在其他场景下能帮我们捕获真正的异步流程遗漏问题。
先看一下你的代码:
'use strict'; var Promise = require('bluebird'); function promised() { return Promise.resolve(); } function backgroundJob() { return Promise.resolve(); } function doBackgroundJob() { // this is an intentional runaway promise. backgroundJob() .catch(function (err) { console.log('error', err); }); } function test() { return promised() .then(function () { doBackgroundJob(); return null; // without this, bluebird displays the warning }); }
解决方案
不需要修改调用方的return null,我们可以在doBackgroundJob内部做处理,明确告诉Bluebird这个Promise是被有意丢弃的,具体有几种实用方法:
方法1:使用void操作符
void会忽略表达式的返回值,这样Bluebird就不会检测到在then handler里存在未返回的Promise:
function doBackgroundJob() { // 用void标记这个Promise是我们主动丢弃的 void backgroundJob() .catch(function (err) { console.log('error', err); }); }
方法2:使用Bluebird的.done()方法
.done()是Bluebird专门用来终止Promise链的方法,它会告诉Bluebird这条异步链已经结束,不需要再跟踪返回值(你这里已经有catch处理错误,所以不会有未捕获异常的问题):
function doBackgroundJob() { backgroundJob() .catch(function (err) { console.log('error', err); }) .done(); // 终止Promise链,消除警告 }
方法3:过滤特定警告(进阶)
如果不想修改doBackgroundJob的代码,还可以通过Bluebird的事件监听精准过滤这个特定警告,同时保留其他有用的警告提示:
Promise.on('warning', function(warning) { // 匹配目标警告信息 if (warning.message.includes('a promise was created in a handler but was not returned from it')) { // 检查调用栈,确认是来自doBackgroundJob的调用 if (warning.stack.includes('doBackgroundJob')) { return; // 忽略这个特定警告 } } // 其他警告正常输出 console.warn(warning.message); });
为什么这些方法有效?
Bluebird的这个警告本质是提醒我们:在Promise的then/catch handler里创建了Promise但没有返回,可能是遗漏了异步流程的串联。而我们的场景是主动放弃跟踪这个后台任务的Promise,所以通过上述方法明确传递这个意图,就能在保留其他警告的同时消除这个不必要的提示。
内容的提问来源于stack exchange,提问作者zeodtr
相关产品推荐
相关产品推荐

