gpt4 book ai didi

node.js - 发出 'stop'事件后如何中止异步功能

转载 作者:行者123 更新时间:2023-12-03 08:21:06 28 4
gpt4 key购买 nike

我试图使一个puppeteer.js机器人能够暂停并恢复其工作。
总的来说,我有一个带有十几个异步方法的类,事件发射器和一个名为“state”的属性,该属性使用setter进行更改。当我发生事件“停止”时,我希望某些异步功能被中止。我该如何实现?

我以为我需要观察this.state何时变为“停止”,并运行return;,但未找到任何解决方案。
然后,我决定尝试在将状态更改为“停止”的事件上设置处理程序,但无法在停止事件上中止处理程序的异步功能。

 constructor() {
this.state = 'none';
this.emiter = new events.EventEmitter();
this.setHandler('stop', () => this.stop());
this.setHandler('resume', () => this.resume());
this.setHandler('onLoginPage', () => this.passAuth());
// ...
// And dozen of other states with its handlers
}
stop= () => this.setState('stoped', true);
resume = () => this.setState(this.getPreviousState());
getPreviousState = () => ...

// Just an example of a state handler. It has async calls as well
// I want to abort this function when event 'stop' is emitted
@errorCatcher()
async passAuth() {
const { credentials } = Setup.Instance;
await this.page.waitForSelector(LOGIN);
await typeToInput(this.page, EMAIL_INPUT, credentials.login);
await typeToInput(this.page, PWD_INPUT, credentials.pass);
await Promise.all([
await this.page.click(LOGIN),
this.page.waitForNavigation({ timeout: 600000 }),
]);
await this.page.waitFor(500);
await DomMutations.setDomMutationObserver(this.page, this.socketEmitter);

// ...
// And dozen of handlers on corresponding state



setState(nextState, resume) {
// Avoiding to change state if we on pause.
// But resume() can force setstate with argument resume = true;
if (this.state === 'stoped' && !resume) return false;
console.log(`\nEmmited FSM#${nextState}`);
this.emiter.emit(`FSM#${nextState}`);
}

setHandler(state, handler) {
this.emiter.on(`FSM#${state}`, async () => {
this.state = state;
console.log(`State has been changed: ${this.getPreviousState()} ==> ${this.state}. Runnig handler.\n`);
//
// On the next line, we run a corresponding handler func,
// like passAuth() for state 'onLoginPage'. It has has to be aborted
// if emiter gets 'FSM#stoped' event.
//
await handler();
});
}

}```

I expect the async functions to be aborted when event emitter emits 'stop';

最佳答案

在本地不可能做到这一点。

另外,还有两种其他方法可以做到这一点。

  • 在调用await后检查您的状态,例如:
  • class Stated {
    async run() {
    await foo()
    if(this.stopped) return
    await bar()
    if(this.stopped) return
    await done()
    }
    }

    const s = new Stated()
    s.run()
  • 使用带有自定义包装的generator而不是async/await
  • // the wrapper
    function co(gen, isStopped = () => false) {
    return new Promise((resolve, reject) => {
    if (!gen || typeof gen.next !== 'function') return resolve(gen)
    onFulfilled()

    function onFulfilled(res) {
    let ret
    try {
    ret = gen.next(res)
    } catch (e) {
    return reject(e)
    }
    next(ret)
    }

    function onRejected(err) {
    let ret
    try {
    ret = gen.throw(err)
    } catch (e) {
    return reject(e)
    }
    next(ret)
    }

    function next(ret) {
    if (ret.done || isStopped()) return resolve(ret.value)
    Promise.resolve(ret.value).then(onFulfilled, onRejected)
    }
    });
    }

    // the following is your code:
    class Stated {
    * run() {
    yield foo()
    yield bar()
    yield done()
    }
    }

    const s = new Stated()
    co(s.run(), () => s.stopped)

    关于node.js - 发出 'stop'事件后如何中止异步功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57021145/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com