Javascript取消异步循环

时间:2020-11-09 20:07:53

标签: javascript

我在一个项目中找到了以下代码:

const fn = async () => {
    let x = 0;
    for(let i = 0; i < 50; i++){
        const res = await api.call(i);
        if(res.someProp) x++;
    }

    return x;
}

我希望能够在中途停止它,这样,如果我再次调用它,它将从头开始并丢弃先前的调用结果。为了避免同时提出两组要求。

2 个答案:

答案 0 :(得分:0)

这应该做:

let token;
const fn = async () => {
    const my = token = Symbol();
    let x = 0;
    for(let i = 0; i < 50 && my == token; i++){
        const res = await api.call(i);
        if(res.someProp) x++;
    }

    return x;
}

尽管调用之间仍然存在一些重叠,但任何下一个fn()调用一旦开始,以前的循环都会中断其迭代。

答案 1 :(得分:0)

您可以使用任何使用外部标志变量的技术来打破循环。

作为解决方法,您可以尝试使用自定义的Promise类(Live demo):

import CPromise from "c-promise2";

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

async function api(i) {
  console.log(`Async API call [${i}]`);
  await delay(100);
  return {};
}

const fn = () =>
  CPromise.from(function* () {
    let x = 0;
    for (let i = 0; i < 50; i++) {
      const res = yield api.call(i);
      if (res.someProp) x++;
    }

    return x;
  });

const cancelablePromise = fn().then(
  () => console.log("Done"),
  (err) => console.log(`Fail: ${err}`) // Fail: CanceledError: canceled 
);

setTimeout(() => {
  cancelablePromise.cancel(); // abort the async sequence (loop) after 3500ms
}, 3500);