2016-04-21 93 views
0

我有一个nodejs express应用程序,并且我使用了一个具有用于执行函数的典型回调接口的库。我的持久层使用基于承诺的方法。我有以下的代码,困扰我从Promise返回非返回函数导致警告

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()函数跳转到下一个中​​间件。它也会返回undefined。任何建议来处理这个?

+0

尝试从回调函数'cb(null,true)'返回'null'。此警告显示创建失控承诺。 [详情](http://bluebirdjs.com/docs/warning-explanations.html#warning-a-promise-was-created-in-a-handler-but-none-were-returned-from-it) – hassansin

+0

感谢回复,但我无法控制cb返回的内容,因为它是一个外部库。例如express中的'next()'方法。 – kgalli

回答

2

那么,正确的解决方案当然是切换到一个框架,不使用节点式回调和利用承诺,以便您可以简单return您的承诺,并不需要调用传递给任何回调您。

如果这是不可能的,你仍然不应该从你的普通代码调用这种回调。警告是正确的,你正在调用做更多异步工作的东西(回调函数)(创建其他的promise),但不会将它返回到你的链中(“忘记”等待它),这是一个常见的错误。您明确return null正确地抑制这个警告,但实际上还有一个更好的方法:
编写代码,如果你已经正在返回的承诺,然后调用.asCallback这是专门为这个目的(包括未发出警告):

getUserByName('dave') 
    .then(function (user) { 
    // check stuff and call the callback with success 
    return true; 
    }) 
    .asCallback(cb) 
1

但是现在我在问自己是否真的在等待回调到 完成?这是处理这种警告的正确方法吗?我有 感觉我做错了。

node.js中的Javascript执行是单线程的,因此代码正在等待cb()中的任何同步代码完成。如果cb()执行异步操作(您收到的警告让我认为是这样),那么您的代码不会等待这些异步操作完成。

您的解决方法是否是处理该警告的正确方法取决于回调中发生了什么以及您的代码是否需要等待该回调中的任何异步操作才能真正完成。如果你的代码不需要等待它们,那么添加空的return就可以了,它只是告诉承诺库,你故意没有返回在.then()处理程序中创建的承诺,这在某些情况下是可以做的。

另一方面,如果您确实需要等待回调内部的异步操作完成,那么您需要回调的帮助以便能够通过返回承诺或为它本身有一个完成回调(尽管在这种情况下承诺会更容易)。