timed promises

90 views
Skip to first unread message

al...@vidao.com

unread,
Jun 25, 2015, 2:09:40 PM6/25/15
to nod...@googlegroups.com
Hello,

Being relatively new to promises, a few months into using them (the native implementation on nodejs) I found myself adding timeout rejections repeatedly. For me it is a very common use case.

I took a quick look and didn't find Promises with built in timeouts. The code below is my wrapper to handle that, it seems to work fine & passes my tests. The 2 questions I have are (1) is there something that's commonly used for this that I missed in my search and (2) if not - does the wrapper seem alright or is there a potential problem?

Thank you!
Alen

var DEFAULT_TIMEOUT = 5000;

var TimedPromise = function(timeoutAfter) {

var _self = this;

var _rejectFunc;
var _resolveFunc;

var _timeoutMs = timeoutAfter ? timeoutAfter : DEFAULT_TIMEOUT;

var _promise = new Promise(function(resolveFunc, rejectFunc) {
_resolveFunc = resolveFunc.bind(this);
_rejectFunc = rejectFunc.bind(this);
});

var _timeout = setTimeout(function() {

if (_rejectFunc) {
_rejectFunc(Error('timeout'));
}
else {

_promise.then = function() {
return Promise.reject(new Error('timeout'));
};
}
},
_timeoutMs
);

_self.resolve = function(arg) {

if (_timeout) {
clearTimeout(_timeout);
}

_resolveFunc(arg);
};

_self.reject = function(arg) {

if (_timeout) {
clearTimeout(_timeout);
}

_rejectFunc(arg);
};

_self.promise = function() {
return _promise;
};

};

exports = module.exports = TimedPromise;



Gustavo Machado

unread,
Jun 25, 2015, 5:06:56 PM6/25/15
to nod...@googlegroups.com
Hi Alen,

Check out the "race" method of promises, might help simplify this a lot.


Cheers,
Gus

--
Job board: http://jobs.nodejs.org/
New group rules: https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
---
You received this message because you are subscribed to the Google Groups "nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+un...@googlegroups.com.
To post to this group, send email to nod...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/4c1b478c-b2ff-453d-b35d-d5a4de967af2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ryan Graham

unread,
Jun 25, 2015, 8:55:24 PM6/25/15
to nod...@googlegroups.com

al...@vidao.com

unread,
Jun 25, 2015, 8:55:30 PM6/25/15
to nod...@googlegroups.com
Hi Gus,

As in: create one promise that auto-rejects after a timeout and have other promises race against it? Smart & interesting timeout implementation, hadn't thought of that. Especially in cases where I would want to time out library calls whose implementation I don't control.

For that promise that times out, I could still use the an instance of TimedPromise, no? ;)

Promise.race((new TimedPromise(1000)).promise(), someLibCall()]).then(...);


Thanks,
Alen

Jan Krems

unread,
Jun 26, 2015, 12:45:07 PM6/26/15
to nod...@googlegroups.com
One problem with using an "external" timeout for the promise is that you (potentially) waste resources. Promises can't be cancelled (yet?) which means that even thought you'll never look at the result, node will still continue to generate the value and take up the same resources doing it, both in your app and potentially on upstream systems. It's often a good idea to push the timeout up to the code that actually knows how to abort/cancel. E.g. adding good timeout logic to your http client or database library (or whatever the thing is you want to time out) which can reject the innermost promise and immediately close the resources.

al...@vidao.com

unread,
Jun 26, 2015, 2:22:53 PM6/26/15
to nod...@googlegroups.com
Thanks Ryan!

That is a very elegant timeout implementation, just add .timeout(ms, msg). And has many other great features, such as cancellation and delays.

I assumed that native implementation will always be faster & safer to use long-term, thought that 3rd party libs were just a placeholder while native APIs are in development. It appears that I was I was very wrong about speed at least:


And seeing how I am implementing features that bluebird already has, the solution seems pretty clear - will switch to bluebird.

Alen

Ryan Graham

unread,
Jun 26, 2015, 5:32:22 PM6/26/15
to nod...@googlegroups.com
If you are interested in native vs. polyfill performance, it is a bit of a recurring theme in lodash and there's some good articles, podcasts, and videos you might be interested in at https://github.com/lodash/lodash/wiki/Resources

~Ryan

al...@vidao.com

unread,
Jun 26, 2015, 9:46:24 PM6/26/15
to nod...@googlegroups.com
Funny I was just reading up on lodash as I saw your post. It's hard to wrap my head around how libraries could perform so much better than native code, but it appears to be a fact.

I saw lazy.js benchmarks where it greatly outperformed lodash, but since then lodash added lazy evaluation as well.

Thanks again,
Alen
Reply all
Reply to author
Forward
0 new messages