Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best general practice to timeout a function in promise [closed]

Promisify a function call with timeouts

I have seen many resources provide similar examples of using Promise.race to timeout a function call within a given period of time. This is a very good example of how Promise.race can be used in practice. Here's some sample code:

function doWithinInterval(func, timeout) {
    var promiseTimeout = new Promise(function (fulfill, reject) {
       // Rejects as soon as the timeout kicks in
       setTimeout(reject, timeout);
    });
    var promiseFunc = new Promise(function (fulfill, reject) {
        var result = func(); // Function that may take long to finish
        // Fulfills when the given function finishes
        fulfill(result);
    });

    return Promise.race([promiseTimeout, promiseFunc]);
}

The simple approach above using Promise.race rejects the promise as soon as the timeout kicks in before func has completed. Otherwise, the project is fulfilled once the func function finishes before the timeout interval.

This sounds good and easy to use.

However, is this the best practice to use timeout in Promise?

Surely, the approach above can be employed if we want to set a timeout against a function call using Promises. The operations still appear to be a good promise. However, is this considered a good practice of using timeout in a Promise? If not, what is the disadvantage of using this?

I've look for alternative approaches, but couldn't find a native Promise way to do this.

Instead, some external Promise libraries offer timeout functionality as follows:

  • Bluebird supplies .timeout()

  • WinJS supplies .timeout() as well

  • Q also comes with .timeout().

However, Promise.timeout() doesn't appear to be part of the standard ECMAScript 6 API (please correct me if I'm wrong). Is there any recommended way to handle timeouts natively with ES6 Promises?

like image 557
TaoPR Avatar asked Jun 19 '15 11:06

TaoPR


People also ask

How do I set timeout on Promise?

setTimeout() is not exactly a perfect tool for the job, but it's easy enough to wrap it into a promise: const awaitTimeout = delay => new Promise(resolve => setTimeout(resolve, delay)); awaitTimeout(300). then(() => console. log('Hi')); // Logs 'Hi' after 300ms const f = async () => { await awaitTimeout(300); console.

Why Promise is executed before setTimeout?

The reason the promise is executing before your timeout is that the promise isn't actually waiting for anything so it resolved right away. @frankies That has more to do with the way Promises are queued and resolved. The focus of my answer is the difference between setTimeout and Promise .

What is .all in Promise?

all() The Promise. all() method takes an iterable of promises as an input, and returns a single Promise that resolves to an array of the results of the input promises. This returned promise will fulfill when all of the input's promises have fulfilled, or if the input iterable contains no promises.

Which are callback used for handling promises?

Promise callbacks are handled as a Microtask whereas setTimeout() callbacks are handled as Task queues.


1 Answers

It depends on what you mean by timeout.

If you expect the function to stop, then no.

If you just want to stop waiting for it, then yes (quick to whip up in ES6):

var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
var timeout = (p, ms) => Promise.race([p, wait(ms).then(() => {
    throw new Error("Timeout after " + ms + " ms");
})]);

var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
var timeout = (p, ms) => Promise.race([p, wait(ms).then(() => {
  throw new Error("Timeout after " + ms + " ms");
})]);

// Example:

var log = msg => div.innerHTML += "<p>" + msg + "</p>";
var failed = e => log(e.toString() + ", line " + e.lineNumber);

log("Waiting 5 seconds...");
timeout(wait(5000), 2000)
.then(() => log("...Done."))
.catch(failed);
<div id="div"></div>

If you want to cancel the operation (make it stop), then hopefully that operation comes with an API to cancel it, and you should use that, since an ES6 promise is not a control surface.

Cancelable promises is a controversial topic in ES6, but some of the libraries mentioned do offer the concept.

like image 80
jib Avatar answered Sep 18 '22 06:09

jib