承诺中的ClearTimeout使用最佳实践

时间:2018-05-02 01:24:24

标签: javascript settimeout cleartimeout

我有一个关于clearTimeout方法的问题(对于noob问题提前抱歉)。我想知道以下代码中clearTimeout的最佳位置在哪里?我有一个“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 :(得分:0)

通常,我会在承诺本身中执行此操作,并避免两个单独承诺的开销。

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(),
  ])
}