我有一个异步函数,该函数具有一个循环,需要它可以暂停或取消暂停它。这是我到目前为止所拥有的。
我使用一个标志来暂停流程:
let flag = true;
function flag_func() {
flag = !flag;
}
$(document).ready(function () {
function sleep(ms) {
while (!flag) {
//...waiting.. but infinite loop
}
return new Promise(resolve => setTimeout(resolve, ms));
}
async function show_simulation(data) {
document.getElementById("solve-button").outerHTML = "<button type=\"button\" id='pause-button' onclick='flag_func()' class=\"btn btn-primary btn-lg\">Pause</button>";
//simulation
if (data.length === 0) {
console.log('stuff')
} else {
let i;
for (i = 0; i < data.length; i++) {
await sleep(40);
// do stuff
}
}
}
});
问题是正在暂停,但是由于
while
阻塞了流程,所以我无法取消暂停for
循环。关于如何解决这个问题的任何想法吗?
最佳答案
对于异步可迭代对象,这可能是一个很好的用例。创建异步列表需要一些样板,但是代码要好得多。基本上,您将拥有:
import AsyncList from './async-list.js'
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
async function f(data) {
const list = new AsyncList(data);
document.getElementById("btn-toggle").addEventListener("click", function () {
if (list.paused) {
this.textContent = "Pause";
list.resume();
} else {
this.textContent = "Resume";
list.pause()
}
})
for await (let item of list) {
console.log(item)
await sleep(1000);
}
console.log("end of loop")
}
f([10, "hello", 1029, 90, 80, 209, 44])
AsyncList
的可能实现是:export default class AsyncList {
constructor(array) {
// shallow copy
this._array = array.slice();
this._index = 0;
this._length = this._array.length;
this.paused = false;
this._resume = () => {}; // noop, in case `resume` is called before `pause`
}
[Symbol.asyncIterator]() {
return this;
}
pause() {
this.paused = true;
}
resume() {
this.paused = false;
this._resume();
}
next() {
if (this._index < this._length) {
const value = this._array[this._index++];
if (this.paused) {
return new Promise(r => this._resume = r.bind(null, { value }))
}
return Promise.resolve({ value })
} else {
return Promise.resolve({ done: true });
}
}
}
只是为了给您一个想法,您还可以封装私有属性,并检查更多方案(例如,这里我假设
data
是一个数组,而不仅仅是一个可迭代的数组)。关于javascript - 异步函数中的javascript中的暂停和取消暂停循环,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51412013/