-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
.done() signifies a promise is handled; chains that end in it are not runaway promises #1491
Comments
Thanks for raising the issue :) First of all -
We have the myPromiseReturningFn().asCallback(cb); // cb is a standard node callback
function callbackApi(cb) {
promiseReturningFn().asCallback(cb);
} |
Hmm, this was the first thing I tried, and I still got the same warnings. I ended up reasoning that asCallback did not mark the promise as final because it returns yet another promise itself. I will investigate further. |
Is the semantics of asCallback() to forward responsibility to the callback passed in? If so, this should always suppress the error; the promise is going to be handled by the callback and bluebird can wash its hands of it. At any rate, I am still seeing this warning with asCallback, so bluebird thinks the promise is not guaranteed to be handled. Here is a distilled version of what a lot of our consuming code is doing that generates the warning:
I have an api that returns an EventEmitter. This EventEmitter uses bluebird for work in its constructor (which is continued by a "connect" event.), and for a .close() function (which emits a "close" event as the promise continuation). These objects will often be created inside new Promise() call, which wires up a global close event handler and completes when the connect event is raised. This is rather unorthodox, but these items are long-lived and intended to run indefinitely. These promises are then stored in an array until the client receives a shutdown signal. I would like to avoid requiring the clients to If asCallback is really contracted as marking the promise as handled, this is probably a bug. Otherwise, I feel that there should be some other way of claiming responsibility of the promise's continuation. |
What version of bluebird is the issue happening on?
3.5.1
What platform and version? (For example Node.js 0.12 or Google Chrome 32)
NodeJS 8.9.1
Did this issue happen with earlier version of bluebird?
Unknown - new usage.
Currently, there seems to be no way for a library that wishes to use promises but expose a callback api without causing floods of false-positive runaway promise warnings if a consuming library then wraps those callbacks in other bluebird promises.
It seems the semantics of .done() indicate that the promise is absolutely at an end and fully handled, so we have been using it for promises that perform setup work inside things like streams, which communicate their readiness over EventEmitter events rather than exporting a promise. As such, any promise chain in which all branches end in a .done() should not be considered a runaway promise error.
After a few minutes of experimentation, I was able to make a trial implementation of this in debuggability.js by calling this function from checkForgottenReturns against
promiseCreated
I have tested this out against our existing code, and it reliably silences the error when the promises are fully handled and end in .done(), and still warns when it detects 'true' runaway promises.
If performance is an issue, a bit field could be added indicating if all children are final, and propagated on each .done() call.
The text was updated successfully, but these errors were encountered: