我有一个异步函数,该函数具有一个循环,我需要将其暂停或取消暂停。这就是我到目前为止所拥有的。
我使用标志来暂停流程:
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
循环。
关于如何解决这个问题的任何想法吗?
答案 0 :(得分:2)
对于异步可迭代对象,这可能是一个很好的用例。创建异步列表需要一些样板,但是代码要好得多。基本上,您会:
my_app/test/controllers/dashboard_controller_test.rb
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 });
}
}
}
是一个数组,而不仅仅是一个可迭代的数组)。
答案 1 :(得分:0)
我要替换:
let i;
for (i = 0; i < data.length; i++) {
await sleep(40);
// do stuff
}
...与...
let i = 0;
const doStuff = () => {
// do stuff
if (++i < data.length) {
setTimeout(doStuff, 40);
}
};
setTimeout(doStuff, 40);