v8 закрытие обещаний вопросы о комментариях в исходном коде - PullRequest
1 голос
/ 03 августа 2020

Я просто смотрел на компилятор v8, а именно на строку в обещании-all-element-closure.tq: и наткнулся на строки.

    // Promise.allSettled, for each input element, has both a resolve and a
    // reject closure that share an [[AlreadyCalled]] boolean. That is, the
    // input element can only be settled once: after resolve is called, reject
    // returns early, and vice versa. Using {function}'s context as the marker
    // only tracks per-closure instead of per-element. When the second
    // resolve/reject closure is called on the same index, values.object[index]
    // will already exist and will not be the hole value. In that case, return
    // early. Everything up to this point is not yet observable to user code.
    // This is not a problem for Promise.all since Promise.all has a single
    // resolve closure (no reject) per element.

Это похоже на исправление ошибки. Я не совсем понимаю, как Promise.allSettled может вызывать отказ от решения для одного и того же элемента более одного раза? В чем была проблема?

1 Ответ

0 голосов
/ 03 августа 2020

Я не совсем понимаю, как Promise.allSettled может вызывать отказ от решения для одного и того же элемента более одного раза?

Promise.allSettled не вызывает их вообще. Код, создающий и устанавливающий обещание, выполняет - и может вызывать их более одного раза. Итак, Promise.allSettled просто обрабатывает этот случай, возвращаясь раньше из функции, в которой вы видели этот комментарий. В случае, когда он не видел урегулирования для обещания по этому индексу, он продолжает работу, поэтому он может заполнить как в массиве, заполнение.

Вот пример функции, которая либо A) вызывает reject один раз, либо B) вызывает resolve хотя бы один раз (возможно, более одного раза), а также вызывает reject:

function findMatchInStream(stream, text) {
    return new Promise((resolve, reject) => {
        stream.on("line", line => {
            if (line.includes(text)) {
                resolve(line);
            }
        });
        stream.on("end", () => reject());
    });
}

Этот код реагирует на событие Node.js -подобное line, проверяя строку на предмет заданного текста и, если он найден, вызывает resolve - даже если он уже вызывал resolve ранее. Точно так же, когда он достигает конца потока, он вызывает reject, даже если он вызывал resolve ранее. Это нормально (хотя, на мой взгляд, бедно), потому что, как только вы уладили обещание, вы уже не сможете уладить его снова ; последующие вызовы resolve или reject игнорируются.

К сожалению, я видел в дикой природе такой код просто .

...