Практика использования ClearTimeout в рамках обещания - PullRequest
0 голосов
/ 02 мая 2018

У меня есть вопрос о методе clearTimeout (заранее извините за вопрос noob). Мне интересно, где лучшее место, чтобы очистить Timeout в этом следующем коде? У меня есть функция "getResponse ()", которая будет вызываться несколько раз. Я не уверен, где было бы лучшее место для установки clearTimeout, чтобы он сбрасывал время ожидания, как только responseTimeout или разрешает, или отклоняет. Спасибо

function getResponse() {
    const responseTimeout = new Promise((resolve, reject) => {
        let id = setTimeout(() => {
            if (!messageHandled) {                       
                reject(`Timed out to get response`);               
            }                      
        }, 3000);
    });

    const responsePromise = new Promise((resolve, reject) => {
        // some code which returns response promise
    });

    return Promise.race([
        responsePromise,
        responseTimeout
    ]);
}

1 Ответ

0 голосов
/ 02 мая 2018

Обычно я делаю это в самом обещании и избегаю накладных расходов двух отдельных обещаний.

function getResponse(...params) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(new Error("Timed out to get response"))

      // some code to abort request
    }, 3000)

    // some code which resolves promise
  })
}

Полезно, обещания игнорируют более поздние решения и / или отклонения после того, как вы решите это в первый раз. Если вы можете программно прервать его, не применяя логику разрешения, это становится намного проще, но даже если вы не можете, вы всегда можете задать логическое значение, чтобы заблокировать будущие запросы. Это также облегчает добавление поддержки отмены позже, что также полезно. Если вам нужно также отключить тайм-аут (если вы делаете какую-то мутацию DOM или чтение файла - вам редко нужно это делать), вы можете сделать что-то вроде этого:

function getResponse(...params) {
  return new Promise((reallyResolve, reallyReject) => {
    let resolved = false
    let id = setTimeout(() => {
      reject(new Error("Timed out to get response"))
      abort()
    }, 3000)

    // I'll use these instead of the `resolve`/`reject` callbacks directly.
    function resolve(value) {
      if (resolved) return
      resolved = true
      clearTimeout(id)
      reallyResolve(value)
    }

    function reject(value) {
      if (resolved) return
      resolved = true
      clearTimeout(id)
      reallyReject(value)
    }

    function abort() {
      // some code to abort request
    }

    // some code which resolves promise
  })
}

Это позволяет мне не беспокоиться об организации всего, но все равно работает.

Если вам не нужна логика прерывания (она действительно нужна только для сетевых запросов и т. П.), Это становится намного проще:

function timeout(ms) {
  return new Promise((_, reject) => {
    setTimeout(() => reject(new Error("Timed out")), ms)
  })
}

function getResponse(...params) {
  return Promise.race([
    timeout(3000),
    doSomethingAsync(),
  ])
}
...