如何确保(并等待)所有 Promise 在 javascript 中都处于已解决状态?

问题描述 投票:0回答:1

我的函数(不是

async
)多次调用getUserMedia(循环中
for
)。
每次调用都会创建一个承诺,然后将调用解析或拒绝处理程序。

循环退出后,我需要确保所有承诺都已解决,收集结果并为

return
执行
function

因此,我需要确保所有承诺都在点 (C) 中解决 - 请参阅以下代码,处理其处理程序的结果,然后退出该函数。
我的代码正确吗?

我很困惑,我的程序会循环等待。

我可以处理(A)点的结果,但是如果我这样做并执行

return
,那么它将退出resolve_handler,但不会退出该函数。

另一方面,如果我处理结果并执行(B)点中的

return
,那么我将无法确保所有承诺都得到解决?

那么,我该如何确保呢?

       let promisesToWait = [];

        for (let constraintIndex = 0; constraintIndex < constraintsArray.length; constraintIndex++) {
            let curConstraints = constraintsArray[constraintIndex];

            let curPromise = navigator.mediaDevices.getUserMedia(curConstraints);
            promisesToWait.push(curPromise);

            // process a promise returned by getUserMedia
            curPromise.then(
            function Resolve_GetUserMedia(stream) {
                // --- there is the resolve_handler ---
            } // function Resolve_GetUserMedia(stream)
            ,

            function Reject_GetUserMedia() {
                // --- there is the reject_handler ---
            } // function Reject_GetUserMedia() {

            );
        } // for (let constraintIndex = 0,

        let allPromises = Promise.allSettled(promisesToWait);

        // --------- wait when all promises will be settled ---------
        let finishWaiting = false;
        allPromises.then(   () => {/*resolve:*/ finishWaiting = true;
        // ================= the point (A)
                                  },
                            () => {/*resolve:*/ finishWaiting = true;}                
        ); // then
        // ====================== the point (B)
        let startTime = Date.now();
        let loopsCounter = 0;
        while (!finishWaiting) {
            loopsCounter++;
        }
        let finishTime = Date.now();
        let waitingDuration = finishTime - startTime;
        // +++ output waiting statistics +++
        let msg = "Wating statistics: time (ms) = " + waitingDuration + ".  Waiting loops = " + loopsCounter;
        DisplayLog2Message(msg);
        console.log(msg);
        // ======================== the point (C)
        // ----------------------------------------------------------------------------
javascript promise
1个回答
0
投票

不建议您当前使用循环等待承诺解决的方法

(while (!finishWaiting))
。它会导致事件循环阻塞,并可能导致性能不佳甚至冻结应用程序。

相反,您应该利用 Promise 的异步特性并使用

await
关键字或处理
then
块内已确定的 Promise。这是使用
async/await
:

的代码的更新版本
async function yourFunction() {
    let promisesToWait = [];

    for (let constraintIndex = 0; constraintIndex < constraintsArray.length; constraintIndex++) {
        let curConstraints = constraintsArray[constraintIndex];

        let curPromise = navigator.mediaDevices.getUserMedia(curConstraints);
        promisesToWait.push(curPromise);

        // Process a promise returned by getUserMedia
        curPromise.then(
            function Resolve_GetUserMedia(stream) {
                // --- there is the resolve_handler ---
            },
            function Reject_GetUserMedia() {
                // --- there is the reject_handler ---
            }
        );
    }

    // Wait for all promises to settle
    await Promise.allSettled(promisesToWait);

    // Process results or perform other actions
    // This point is reached only when all promises are settled
    // ================= the point (C)
    // ...

    // You can return something here if needed
}

// Call your function
yourFunction().then(() => {
    // Any code you want to execute after all promises are settled
}).catch((error) => {
    console.error("Error:", error);
});

通过使用

await Promise.allSettled(promisesToWait)
,您可以确保函数不会继续超出该点,直到所有承诺都得到解决。
then
后面的
await
块是您可以在所有承诺都解决后处理结果或执行操作的地方。此外,使用
async/await
使代码更具可读性并避免阻塞事件循环。

© www.soinside.com 2019 - 2024. All rights reserved.