我怎样才能取消javascript等待睡眠?

我怎样才能取消javascript等待睡眠?,javascript,Javascript,javascript中最常见的睡眠函数实现是在setTimeout解析后返回承诺: function sleep(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } 我使用了for循环和wait sleep来防止它执行得太快,比如不请求xhr太快。我在别处还有一个isBreak标志,告诉我何时停止for循环。然而,我遇到的问题是,当我中断for循环时,先前的等待睡眠已经执行,并且正在

javascript中最常见的睡眠函数实现是在setTimeout解析后返回承诺:

function sleep(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}
我使用了for循环和wait sleep来防止它执行得太快,比如不请求xhr太快。我在别处还有一个isBreak标志,告诉我何时停止for循环。然而,我遇到的问题是,当我中断for循环时,先前的等待睡眠已经执行,并且正在阻塞for循环。有没有更好的方法来打破for循环并同时终止等待睡眠

const items = [];

let isBreak = false; // Somewhere else in the application

for (const item of items) {
  if (isBreak) break;

  // Do something, like xhr request
  await sleep(15000); // 15 seconds sleep

  if (isBreak) break;
}

在JS中,有没有一种方法可以让我为早期的

发出信号,当一个
等待
操作开始时,它不能再被中断;它将等待其操作数承诺得到解决

因此,你必须以某种方式取消你正在等待的承诺

不幸的是,您的代码无法收到关于变量重新分配的通知(当您将
isBreak
设置为
true
时),并且轮询它将效率低下

您可以使用
AbortSignal
(为此而发明)代替标志,并使您的
睡眠
接受一个:

function sleep(ms, signal) {
  return new Promise((resolve, reject) => {
    const timeout = setTimeout(() => {
      resolve();
      signal.removeEventListener('abort', abort);
    }, ms);
    const abort = () => {
      clearTimeout(timeout);
      reject(new Error('Cancelled'));
    }
    if(signal.aborted)
      abort();
    else
      signal.addEventListener('abort', abort);
  });
}
然后,您可以这样使用它:

const items=[];
const isBreak=new AbortController();//在应用程序的其他地方,调用'isBreak.abort()`
试一试{
用于(项目的常数项){
//做一些事情,比如xhr请求
等待睡眠(15000,isBreak.signal);//15秒睡眠
}
}捕获(e){
如果(如消息==='已取消'){
//办理取消手续
console.log('Cancelled');
}否则{
//不是取消,请重新播放
投掷e;
}
}

中止信号
也适用于
获取
,如果你也必须取消它。

如果你真的需要实现承诺,FZs的回答很好。但是,你考虑过只使用
设置间隔
并取消间隔吗?我完全忘了添加事件信号。这应该行得通。谢谢