簡體   English   中英

無限 asyncIterator 未按預期工作

[英]Infinite asyncIterator is not working as expected

所以我試圖創建一個無限的 asyncIterator/generator。 該代碼應該為“for await of”循環產生“Hello”和“Hi”,然后永遠等待下一個值。 問題是它不會等待第三個值,也不會在循環后打印 2 並且沒有錯誤地終止。

在 Node v12.14.0 上使用 ts-node 運行。

 class Source<T> {

    _data: T[] = [];
    _queue: ((val: T) => void)[] = [];

    send(val: T) {
        if (this._queue.length > 0) {
            this._queue.shift()!(val);
        } else {
            this._data.push(val);
        }
    }

    next(): Promise<{ done: boolean, value: T }> {
        return new Promise((resolve, _reject) => {
            if (this._data.length > 0) {
                resolve({ done: false, value: this._data.shift()! });
            } else {
                this._queue.push(value => resolve({ done: false, value }));
            }
        });
    }

    [Symbol.asyncIterator]() {
        return this;
    }

}

(async () => {
    const s = new Source<String>();
    s.send("Hello");
    s.send("Hi");

    console.log(1);

    for await (let str of s) {
        console.log(str);
    }

    console.log(2);
})();

未解決的承諾不會阻止退出進程。 看看這個

只要有一個已解決的承諾和一個跟隨它的鏈,這個過程就會繼續運行。 由於您在for await之前調用了s.send()幾次,循環中的前兩次迭代已經解決了 promise,因此需要運行更多代碼。 在此之后,它等待未解決的承諾,這使您對(async () => { ... })()的調用成為未解決的承諾。 不再運行代碼,進程退出。

為了解決這個問題,你可以做一些討厭的事情,比如setInterval(() => {}, 999999999) 只要有超時安排,進程就不會退出。

我花了一段時間才弄清楚在什么情況下我們會想要這種行為——而不是等到所有承諾都被解決或拒絕后才退出。

let p1 = Promise.resolve(1),
    p2 = new Promise(() => {}).then(Promise.resolve(2)),
    p3 = Promise.race([p1, p2]).then(console.log);

p2永遠不會解析,並且p3Promise.race()調用不會取消p2then() 然而,我們希望這個程序打印1然后退出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM