我有一个nodejs express app,我使用的库有一个典型的回调接口来执行函数。我的持久层使用基于承诺的方法。我有以下代码困扰我
getUserByName('dave')
.then(function (user) {
// check stuff and call the callback with success
return cb(null, true);
})
.catch((err) => cb(err, false));
问题:cb(null, true)
函数返回undefined
,承诺以此警告a promise was created in a handler but was not returned from it
结束。
我可以通过运行回调来解决这个问题,然后执行return null
这样的操作:
// check stuff and call the callback with success
cb(null, true);
return null;
但现在我问自己是否真的在等待回调结束?这是处理此类警告的正确方法吗?我觉得我做错了。
我记得在编写快速中间件时遇到同样的问题,然后在调用next()
函数的promise中跳转到下一个中间件。它还返回undefined
。有任何建议可以解决这个问题吗?
答案 0 :(得分:2)
嗯,正确的解决方案当然是切换到一个不使用节点式回调并利用承诺的框架,这样你就可以简单地return
你的承诺而不需要调用任何回调传递给你。
如果无法做到这一点,您仍然不应该从普通代码中调用此类回调。警告是正确的,你正在调用一些(回调)做更多的异步工作(创建其他承诺),但没有将它返回到你的链(“忘记”等待它),这是一个常见的错误。您明确的return null
会正确地抑制此警告,但实际上有更好的方法:
编写代码就像你已经返回了promises一样,然后调用专用于此目的的.asCallback
(包括不发出警告):
getUserByName('dave')
.then(function (user) {
// check stuff and call the callback with success
return true;
})
.asCallback(cb)
答案 1 :(得分:1)
但现在我问自己是否真的在等待回调 完?这是处理此类警告的正确方法吗?我有 感觉我做错了。
node.js中的Javascript执行是单线程的,因此代码正在等待cb()
中的任何同步代码完成。如果cb()
执行异步操作(您收到的警告让我认为是这样),那么您的代码不会等待这些异步操作完成。
您的解决方法是否是处理该警告的正确方法取决于回调中发生的事情以及您的代码是否需要等待该回调中的任何异步操作实际完成。如果您的代码不需要等待它们,那么添加空return
就完全没问了,只是告诉promise库你故意不返回在.then()
处理程序中创建的promise。在某些情况下可以做的事情。
另一方面,如果你确实需要等待回调内部的异步操作完成,那么你需要回调的帮助才能做到这一点,让它返回一个承诺或者它本身就有一个完成回调(虽然在这种情况下承诺会更容易)。