为什么我没有收到警告 "a promise was created in a handler but was not returned from it"?
Why do I not get the warning "a promise was created in a handler but was not returned from it"?
编辑:更清楚 - 我在下面的示例中没有收到警告。我想知道为什么并查看打印警告的示例代码。
在我的 Node.js 项目中,我使用 bluebird Promises 库。我观察到某些情况下会收到以下警告:
Warning: a promise was created in a handler but was not returned from it
我了解当存在未连接到任何承诺链的承诺时会出现问题。
我正在尝试完全理解它是如何工作的,以及上述案例中的问题到底是什么。为此,我以 the documentation.
为例
这是我的代码示例,它基于我没有收到任何警告的文档中的示例:
const Promise = require('bluebird');
function getUser() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('get user');
resolve('userId');
}, 4000);
});
}
function getUserData(userId) {
new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('get user data');
resolve('userData');
}, 5000);
});
}
getUser().then(function(user) {
getUserData(user);
}).then(function(userData) {
// userData is undefined as expected
console.log('Data: ', userData);
});
控制台输出:
/usr/local/opt/node@6/bin/node test.js
get user
Data: undefined
get user data
Process finished with exit code 0
有谁知道为什么我的案例没有警告以及如何重现?
编辑:我使用的是 Node v6.11.3 和 Bluebird 3.1.1
根据 Pierre Clocher 的回答,我也尝试了以下内容:
getUser().then(function(user) {
getUserData(user);
}).then(function(userData) {
console.log('Data: ', userData);
// userData is undefined
throw new Error();
}).catch(function (error) {
console.log('error: ', error);
});
也没有任何警告。
控制台输出:
/usr/local/opt/node@6/bin/node test.js
get user
Data: undefined
error: Error
at test.js:64:11
at tryCatcher (/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/node_modules/bluebird/js/release/promise.js:693:18)
at Async._drainQueue (/node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (/node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues (/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:672:20)
at tryOnImmediate (timers.js:645:5)
at processImmediate [as _immediateCallback] (timers.js:617:5)
get user data
Process finished with exit code 0
检查Bluebird.js来源
如果有人更熟悉 Bluebird 源代码,我搜索了整个源代码并找到了检查警告的地方 (link to source):
if (returnValue === undefined && promiseCreated !== null &&
wForgottenReturn) {
....
}
var msg = "a promise was created in a " + name +
"handler " + handlerLine + "but was not returned from it, " +
"see <link to goo.gl removed>" +
creatorLine;
promise._warn(msg, true, promiseCreated);
使用我检查过的调试器,returnValue 在我的案例中未定义,wForgottenReturn 标志设置为 true 但 promiseCreated 为空,因此未打印警告。在我的示例中,我会将此解释为 Promise via getUserData(user) was not detected as created/unhandled.
回调里面需要写return
.then(function(data){return getusersata()})
这样你需要 return 在 getuserdata
中承诺
return new Promise
问题是抛出了一个错误,而您的承诺流程中没有任何 .catch()
方法。你的例子没有抛出任何东西,这就是为什么你没有任何警告。
尝试一下,您会看到警告:
getUser().then(function(user) {
return getUserData(user);
}).then(function(userData) {
// userData is undefined => now it is (you need to return previous Promise)
throw new Error();
});
这里会因为报错而出现警告。但是如果你加上 .catch(console.error)
就不会了。
我会回答我自己的问题,因为我找到了问题所在。
简短回答:问题是只有在配置启用时才会在控制台中打印警告。
解释:
在网上搜索时,我在 Bluebird github 上找到了这个 issue reported。在示例代码中,我看到他们使用以下代码手动更新了 Bluebird 配置:
Promise.config({
warnings: true,
longStackTraces: true
});
我之前也是这样做的 运行 我的代码:
Promise.config({
warnings: true,
longStackTraces: true
});
function getUser() {
...
}
function getUserData(userId) {
...
}
getUser().then(function(user) {
getUserData(user);
}).then(function(userData) {
// userData is undefined as expected
console.log('Data: ', userData);
});
最终输出带有警告:
/usr/local/opt/node@6/bin/node test.js
get user
(node:96276) Warning: a promise was created in a handler at test.js:71:5 but was not returned from it, see <goo.gl link removed>
at new Promise (node_modules/bluebird/js/release/promise.js:79:10)
Data: undefined
get user data
Process finished with exit code 0
进一步检查我还发现,如果 NODE_ENV 变量设置为 "development",则无需手动设置 Bluebird 配置即可查看警告。在 "development" 的情况下,此类功能会自动启用。 this API reference.
中也对此进行了描述
编辑:更清楚 - 我在下面的示例中没有收到警告。我想知道为什么并查看打印警告的示例代码。
在我的 Node.js 项目中,我使用 bluebird Promises 库。我观察到某些情况下会收到以下警告:
Warning: a promise was created in a handler but was not returned from it
我了解当存在未连接到任何承诺链的承诺时会出现问题。
我正在尝试完全理解它是如何工作的,以及上述案例中的问题到底是什么。为此,我以 the documentation.
为例这是我的代码示例,它基于我没有收到任何警告的文档中的示例:
const Promise = require('bluebird');
function getUser() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('get user');
resolve('userId');
}, 4000);
});
}
function getUserData(userId) {
new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('get user data');
resolve('userData');
}, 5000);
});
}
getUser().then(function(user) {
getUserData(user);
}).then(function(userData) {
// userData is undefined as expected
console.log('Data: ', userData);
});
控制台输出:
/usr/local/opt/node@6/bin/node test.js
get user
Data: undefined
get user data
Process finished with exit code 0
有谁知道为什么我的案例没有警告以及如何重现?
编辑:我使用的是 Node v6.11.3 和 Bluebird 3.1.1
根据 Pierre Clocher 的回答,我也尝试了以下内容:
getUser().then(function(user) {
getUserData(user);
}).then(function(userData) {
console.log('Data: ', userData);
// userData is undefined
throw new Error();
}).catch(function (error) {
console.log('error: ', error);
});
也没有任何警告。
控制台输出:
/usr/local/opt/node@6/bin/node test.js
get user
Data: undefined
error: Error
at test.js:64:11
at tryCatcher (/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/node_modules/bluebird/js/release/promise.js:693:18)
at Async._drainQueue (/node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (/node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues (/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:672:20)
at tryOnImmediate (timers.js:645:5)
at processImmediate [as _immediateCallback] (timers.js:617:5)
get user data
Process finished with exit code 0
检查Bluebird.js来源
如果有人更熟悉 Bluebird 源代码,我搜索了整个源代码并找到了检查警告的地方 (link to source):
if (returnValue === undefined && promiseCreated !== null &&
wForgottenReturn) {
....
}
var msg = "a promise was created in a " + name +
"handler " + handlerLine + "but was not returned from it, " +
"see <link to goo.gl removed>" +
creatorLine;
promise._warn(msg, true, promiseCreated);
使用我检查过的调试器,returnValue 在我的案例中未定义,wForgottenReturn 标志设置为 true 但 promiseCreated 为空,因此未打印警告。在我的示例中,我会将此解释为 Promise via getUserData(user) was not detected as created/unhandled.
回调里面需要写return
.then(function(data){return getusersata()})
这样你需要 return 在 getuserdata
中承诺return new Promise
问题是抛出了一个错误,而您的承诺流程中没有任何 .catch()
方法。你的例子没有抛出任何东西,这就是为什么你没有任何警告。
尝试一下,您会看到警告:
getUser().then(function(user) {
return getUserData(user);
}).then(function(userData) {
// userData is undefined => now it is (you need to return previous Promise)
throw new Error();
});
这里会因为报错而出现警告。但是如果你加上 .catch(console.error)
就不会了。
我会回答我自己的问题,因为我找到了问题所在。
简短回答:问题是只有在配置启用时才会在控制台中打印警告。
解释:
在网上搜索时,我在 Bluebird github 上找到了这个 issue reported。在示例代码中,我看到他们使用以下代码手动更新了 Bluebird 配置:
Promise.config({
warnings: true,
longStackTraces: true
});
我之前也是这样做的 运行 我的代码:
Promise.config({
warnings: true,
longStackTraces: true
});
function getUser() {
...
}
function getUserData(userId) {
...
}
getUser().then(function(user) {
getUserData(user);
}).then(function(userData) {
// userData is undefined as expected
console.log('Data: ', userData);
});
最终输出带有警告:
/usr/local/opt/node@6/bin/node test.js
get user
(node:96276) Warning: a promise was created in a handler at test.js:71:5 but was not returned from it, see <goo.gl link removed>
at new Promise (node_modules/bluebird/js/release/promise.js:79:10)
Data: undefined
get user data
Process finished with exit code 0
进一步检查我还发现,如果 NODE_ENV 变量设置为 "development",则无需手动设置 Bluebird 配置即可查看警告。在 "development" 的情况下,此类功能会自动启用。 this API reference.
中也对此进行了描述