javascript - 如何取消 Javascript Promise 中的超时?

标签 javascript promise settimeout cancellation

我在 JavaScript 中玩弄 promise 并尝试 promise setTimeout 函数:

function timeout(ms) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve('timeout done');
    }, ms);
  }); 
}

var myPromise=timeout(3000); 

myPromise.then(function(result) { 
  console.log(result); // timeout done
})

相当简单,但我想知道在 promise 解决之前我将如何取消我的超时。 timeout 返回 Promise 对象,因此我失去了对 setTimeout 返回的值的访问权限,并且无法通过 clearTimeout 取消超时。最好的方法是什么?

顺便说一句,这没有真正的目的,我只是想知道如何解决这个问题。我也把它放在这里了http://plnkr.co/edit/NXFjs1dXWVFNEOeCV1BA?p=preview

最佳答案

Edit 2021 所有平台都已将 AbortController 融合为取消原语,并且有一些内置支持。

在 Node.js 中

// import { setTimeout } from 'timers/promises' // in ESM
const { setTimeout } = require('timers/promises');
const ac = new AbortController();

// cancellable timeout
(async () => {
  await setTimeout(1000, null, { signal: ac.signal });
})();

// abort the timeout, rejects with an ERR_ABORT
ac.abort();

在浏览器中

您可以填充此 API 并使用与上述示例相同的内容:


function delay(ms, value, { signal } = {}) {
    return new Promise((resolve, reject) => {
        const listener = () => {
            clearTimeout(timer);
            reject(signal.reason);
        };
        signal?.throwIfAborted();
        const timer = setTimeout(() => {
            signal?.removeEventListener('abort', listener);
            resolve(value);
        }, ms);
        signal?.addEventListener('abort', listener);
    });
}

您可以这样做,您可以从 timeout 函数返回一个取消器并在需要时调用它。这样您就不需要在全局(或在外部范围内)存储 timeoutid,而且这也可以管理对该函数的多次调用。函数 timeout 返回的对象的每个实例都有自己的取消器,可以执行取消。

function timeout(ms) {
  var timeout, promise;

  promise = new Promise(function(resolve, reject) {
    timeout = setTimeout(function() {
      resolve('timeout done');
    }, ms);
  }); 

  return {
           promise:promise, 
           cancel:function(){clearTimeout(timeout );} //return a canceller as well
         };
}

var timeOutObj =timeout(3000); 

timeOutObj.promise.then(function(result) { 
  console.log(result); // timeout done
});

//Cancel it.
timeOutObj.cancel();

Plnkr

关于javascript - 如何取消 Javascript Promise 中的超时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25345701/

相关文章:

javascript - 什么是 `vsc-initialized` ?

javascript - 防止持久状态锁定 VueX 中的应用程序

javascript - 如何通过传递参数在 JavaScript 中设置计时器

javascript - setTimeout 测试未按预期运行

javascript - JSON.parse 不运行

javascript - 如何过滤数据表中的日期?

angular - 向返回 promise 的 javascript 方法添加延迟

Javascript 如何在运行下一行代码之前等待 x 秒?

javascript - 带有简单数组的基本 ng-repeat

javascript - 如何在嵌套映射函数中进行并发异步调用