Какова наилучшая общая практика тайм-аута функции в promise [закрыто]

Promisify вызов функции с таймаутами

Я видел, что многие ресурсы предоставляют аналогичные примеры использования Promise.race тайм-аута вызова функции в течение заданного периода времени. Это очень хороший пример того, как Promise.race можно использовать на практике. Вот пример кода:

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]);
}

простой подход, с помощью Promise.race отклоняет обещание, как только тайм-аут срабатывает до func завершено. В противном случае, проект выполняется один раз func заканчивает работу до времени.

это звучит хорошо и легко в использовании.

однако, это лучшая практика для использования тайм-аута в Promise?

конечно, подход выше может быть использован, если мы хотим установить тайм-аут против вызова функции с помощью обещаний. Операции по-прежнему кажутся хорошим обещанием. Однако считается ли это хорошей практикой использования тайм-аута в обещании? Если нет, то что недостаток использования этого?

я искал альтернативные подходы, но не мог найти родной способ обещания сделать это.

вместо этого некоторые внешние библиотеки обещаний предлагают timeout функции следующим образом:

  • птица поставок .timeout()

  • библиотеки WinJS поставок .timeout() as ну!--14-->

  • Q также с .timeout().

, Promise.timeout() не является частью стандартного API ECMAScript 6 (пожалуйста, поправьте меня, если я ошибаюсь). Есть ли рекомендуемый способ обработки тайм-аутов изначально с обещаниями ES6?

2 ответов


Это зависит от того, что вы имеете в виду автоотключение.

Если вы ожидаете, что функция остановить, то нет.

Если вы просто хотите перестать ждать его, то да (быстро взбить в 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>

Если вы хотите отмена операция (остановите ее), затем, надеюсь, эта операция поставляется с API для ее отмены, и вы должны использовать это, так как обещание ES6 не является элементом управления поверхность.

отменено обещания является спорной темой в ES6, но некоторые из упомянутых библиотек предлагают концепцию.


родное обещание.метод гонки не очищает таймер обещания тайм-аута после завершения фактического обещания, поэтому процесс будет ждать, пока обещание тайм-аута также не будет завершено. Это означает, что если вы установите тайм-аут в 1h, и наше обещание будет завершено после 1min, то процесс будет ждать 59min, прежде чем он выйдет.

вместо этого используйте этот метод:

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;
    })
  ]);
}