首页 > 解决方案 > 强制停止范围外的生成器功能

问题描述

我有一个生成器功能,我想包括在单击(或通常在事件触发时)停止它的可能性。我可以使用在每次迭代时检查的变量,如果我想停止,将其设置为 true,并且它可以工作,但直到当前迭代得到解决,这使得它在无限循环的情况下无用。

这是一个例子:

const readline = require('readline');
readline.emitKeypressEvents(process.stdin);

const script = class {
    constructor(name, textCode){
        this.name = name;
        this.forceStop = false;
        this.generator = null;

        try {
            textCode += `if(typeof start !== 'undefined') this.start = start;`
            eval(textCode);
        } catch (error) {
            throw error;
        }
        console.log("Loaded.")
    }
    
    async run() {
        try{
            this.generator = this.start();

            console.log("Executing, press Enter to stop..")
            let s = 1;
            let nextValue;
        
            while (true) {
                const next = this.generator.next(nextValue);
                
                nextValue = await next.value; //Here the generator awaits indefinitely for a promise resolve, but I want the possibility to trigger a stop.

                if (next.done === true || nextValue === false || nextValue == "stop" || this.forceStop) {
                    console.log("Over.")
                    break;
                }
                s++;
            }
        } catch(e){
            console.log(e.message)
        }
    }
    
    stop(){
        //stop here, i tried using this.generator.return("stop") but it doesn't work.
        
        this.forceStop = true;
        //this.forceStop works to stop before the whole generator is over but it doesn't solve the problem of not being able to stop while waiting for a promise.
        console.log("Stopped.");
    }
}



const code = `
    function* start(){
        yield new Promise(r => setInterval(()=>{
            console.log("Generator:", Math.random())
        }, 1000));
        
        yield console.log("Generator: script over.")
    }
`

const example = new script("infinite loop", code)

example.run();

//And i wanna be able to call example.stop() whenever and instantly stop it.
process.stdin.on('keypress', (str, key) => {
    if(key.name == "enter") example.stop()
});

标签: node.jsgenerator

解决方案


推荐阅读