有前途的函数超时的最佳通用实践是什么

时间:2022-09-15 20:47:07

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:

我看到许多资源提供了使用Promise的类似示例。在给定的时间内对函数调用进行争用超时。这是承诺的一个很好的例子。比赛可以在实践中使用。这里有一些示例代码:

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.

上面简单的方法就是承诺。比赛拒绝承诺,一旦暂停开始之前,func已经完成。否则,当func函数在超时间隔之前完成时,项目就完成了。

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()

    蓝鸟供应.timeout()

  • WinJS supplies .timeout() as well

    WinJS还提供.timeout()

  • Q also comes with .timeout().

    还有.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?

但是,promip .timeout()似乎不是标准ECMAScript 6 API的一部分(如果我错了,请纠正我)。有什么推荐的方法来处理超时,以ES6承诺?

2 个解决方案

#1


10  

It depends on what you mean by timeout.

这取决于你说的超时是什么意思。

If you expect the function to stop, then no.

如果您期望函数停止,那么no。

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

如果你只是想停止等待,那么是的(在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.

如果您想要取消操作(让它停止),那么希望这个操作有一个API来取消它,并且您应该使用它,因为ES6承诺不是一个控制表面。

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

在ES6中取消承诺是一个有争议的话题,但是提到的一些图书馆确实提供了这个概念。

#2


3  

The native Promise.race method doesn't clear the timer of the timeout promise after the actual promise completes thus the process will wait until the timeout promise is also complete. This means that if you set the timeout to 1h and our promise is completed after 1min then the process will wait for 59min before it exits.

本机的承诺。race方法没有在实际承诺完成后清除超时承诺的计时器,因此进程将等待直到超时承诺也完成。这意味着如果您将超时设置为1h,并且我们的承诺在1min之后完成,那么进程将等待59min后才退出。

Use this method instead:

使用这种方法:

export function race({promise, timeout, error}) {
  let timer = null;

  return Promise.race([
    new Promise((resolve, reject) => {
      timer = setTimeout(reject, timeout, error);
      return timer;
    }),
    promise.then((value) => {
      clearTimeout(timer);
      return value;
    })
  ]);
}

#1


10  

It depends on what you mean by timeout.

这取决于你说的超时是什么意思。

If you expect the function to stop, then no.

如果您期望函数停止,那么no。

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

如果你只是想停止等待,那么是的(在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.

如果您想要取消操作(让它停止),那么希望这个操作有一个API来取消它,并且您应该使用它,因为ES6承诺不是一个控制表面。

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

在ES6中取消承诺是一个有争议的话题,但是提到的一些图书馆确实提供了这个概念。

#2


3  

The native Promise.race method doesn't clear the timer of the timeout promise after the actual promise completes thus the process will wait until the timeout promise is also complete. This means that if you set the timeout to 1h and our promise is completed after 1min then the process will wait for 59min before it exits.

本机的承诺。race方法没有在实际承诺完成后清除超时承诺的计时器,因此进程将等待直到超时承诺也完成。这意味着如果您将超时设置为1h,并且我们的承诺在1min之后完成,那么进程将等待59min后才退出。

Use this method instead:

使用这种方法:

export function race({promise, timeout, error}) {
  let timer = null;

  return Promise.race([
    new Promise((resolve, reject) => {
      timer = setTimeout(reject, timeout, error);
      return timer;
    }),
    promise.then((value) => {
      clearTimeout(timer);
      return value;
    })
  ]);
}