异步函数中的javascript中的暂停和取消暂停循环

时间:2018-07-18 22:48:28

标签: javascript

我有一个异步函数,该函数具有一个循环,我需要将其暂停或取消暂停。这就是我到目前为止所拥有的。

我使用标志来暂停流程:

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循环。

关于如何解决这个问题的任何想法吗?

2 个答案:

答案 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);