cujojs / when

A solid, fast Promises/A+ and when() implementation, plus other async goodies.
Other
3.44k stars 396 forks source link

timeout on joined promises #334

Closed jefflage closed 10 years ago

jefflage commented 10 years ago

assume some code that looks like this:

external_resource_1.do_something().then(function(id){
  return external_resource_2.do_something(id);
})

those two different external resources have different expectations for how long i should wait for a response before i consider them timedout. how can i set independent timeouts for the two different as i think this:

external_resource_1.do_something().then(function(id){
  return external_resource_2.do_something(id);
}).timeout(2000)

would set a timeout for the combined/joined process and include both external resources

thanks

briancavalier commented 10 years ago

Hey @jefflage, if you need the two tasks to execute sequentially without overlap, like in your example, and you need different timeouts for the two sequential steps, you can just call .timeout on each:

var result = external_resource_1.do_something().timeout(1000).then(function(id){
  return external_resource_2.do_something(id).timeout(2000);
});

If resource_1 fails to fulfill in 1 second, result will reject (and consequently, resource_2.do_something will never be invoked). If resource_1 does fulfill in under 1 second, but then subsequently resource_2 fails to fulfill in 2 additional seconds, result will also reject.

Depending on your exact needs and the particular use case, you could move the inner .timeout(2000), to out to the end of the whole chain as you showed it above.

var result = external_resource_1.do_something().timeout(1000).then(function(id){
  return external_resource_2.do_something(id);
}).timeout(2000);

The semantics are subtly different. This later one allows at most 2 seconds for the whole thing, where as the earlier would allow up to 3 seconds for the whole thing.

On the other hand, if you want the two tasks to proceed in parallel with different timeouts, when.all (or when.join), or when.settle might be good choices, again depending on the particular scenario.

var result = when.all([external_resource_1.do_something().timeout(1000), external_resource_2.do_something().timeout(2000)]);

var settledStates = when.settle([external_resource_1.do_something().timeout(1000), external_resource_2.do_something().timeout(2000)]);

Have a look at the docs for those to see which might fit your use case. If anything's not clear in the docs, feel free to post :)

Did that help?

jefflage commented 10 years ago

@briancavalier , your first example is exactly what i need. for some reason, i assume that first call to timeout() would end up applying to the joined promise and not to the first operation. but i get it now.

thanks again.