javascript - 嵌套异步 promise : how to know when they're all resolved?

标签 javascript promise es6-promise

我正在从网络应用程序进行一些 API 调用。首先,我获取我的合作伙伴详细信息(一组酒店)。该合作伙伴拥有一些属性。对于每个属性,我需要获取他们的房间;然后对于每个房间,我需要获取它们的可用性和预订。 我想异步执行所有这些调用(即,一旦我获得了酒店的房间信息,我就可以获得他们的预订和空房情况,而无需等待所有酒店的详细信息)。 我想知道什么时候一切都加载完毕。下面是使用超时来模拟 API 调用的简化代码。

我尝试将每个新的 Promise 推送到数组中,并在此数组上使用 Promise.all,但遇到了同样的问题。

我还尝试在每次进行查询时增加计数器,并在每次解决查询时减少计数器;这是可行的,但看起来不太干净?

        const getPartner = () => {
            const p = new Promise((resolve) => {
                setTimeout(() => {
                    console.log('getPartner finished');
                    resolve({
                        properties: [1, 2, 3],
                    });
                }, 1000);
            });
            return p;
        }

        const getRooms = () => {
            const p = new Promise((resolve) => {
                setTimeout(() => {
                    console.log('getRooms finished');
                    resolve([1, 2, 3]);
                }, 1000);
            });
            return p;
        }

        const getAvailabilities = () => {
            const p = new Promise((resolve) => {
                setTimeout(() => {
                    console.log('getAvailabilities finished');
                    resolve([1, 2, 3]);
                }, 1000);
            });
            return p;
        }

        const getBookings = () => {
            const p = new Promise((resolve) => {
                setTimeout(() => {
                    console.log('getBookings finished');
                    resolve([1, 2, 3]);
                }, 1000);
            });
            return p;
        }

        function main() {
            getPartner().then((partner) => {
                Promise.all([
                    partner.properties.forEach((property) => {
                        getRooms().then((rooms) => {
                            rooms.forEach((room) => {
                                getAvailabilities();
                                getBookings();
                            })
                        });
                    })
                ]).then(() => {
                    console.log('all finished');
                });
            });
        }

        main();

我希望“全部完成”最后显示在控制台中。相反,它会在“getPartner finish”之后立即显示

编辑:这是我尝试使用计数器的方法:

const promises = [];

        const getPartner = () => {
            const p = new Promise((resolve) => {
                setTimeout(() => {
                    console.log('getPartner finished');
                    resolve({
                        properties: [1, 2, 3],
                    });
                }, 1000);
            });
            promises.push(p);
            return p;
        }

        const getRooms = () => {
            const p = new Promise((resolve) => {
                setTimeout(() => {
                    console.log('getRooms finished');
                    resolve([1, 2, 3]);
                }, 1000);
            });
            promises.push(p);
            return p;
        }

        const getAvailabilities = () => {
            const p = new Promise((resolve) => {
                setTimeout(() => {
                    console.log('getAvailabilities finished');
                    resolve([1, 2, 3]);
                }, 1000);
            });
            promises.push(p);
            return p;
        }

        const getBookings = () => {
            const p = new Promise((resolve) => {
                setTimeout(() => {
                    console.log('getBookings finished');
                    resolve([1, 2, 3]);
                }, 1000);
            });
            promises.push(p);
            return p;
        }

        function main() {
            getPartner().then((partner) => {
                partner.properties.map((property) => {
                    getRooms().then((rooms) => {
                        getAvailabilities();
                        getBookings();
                    })
                })
            })
            .then(() => {
                Promise.all(promises).then(() => {
                    console.log('all finished');
                });
            });
        }

        main();

最佳答案

几个问题:

  • forEach 不会返回任何内容,但您应该返回一个数组——以提供给 Promise.all

  • 在有多个 Promise 的每种情况下使用 Promise.all

  • 每当您需要在 then 回调中链接一个 promise 时,请返回 promise

它的工作原理如下:

function main() {
    getPartner().then((partner) => {
        return Promise.all(partner.properties.map((property) => {
            return getRooms().then((rooms) => {
                return Promise.all(rooms.map((room) => {
                    return Promise.all([getAvailabilities(), getBookings()]);
                }))
            });
        })).then(() => {
            console.log('all finished');
        });
    });
}

关于javascript - 嵌套异步 promise : how to know when they're all resolved?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56834388/

相关文章:

Javascript 变量在撇号后被 chop

javascript - Vue Js 应用程序抛出 Js 预期错误

javascript - jQuery .done 未按预期返回

reactjs - 调用 firestore collection() 在博览会上不起作用

javascript - 如何处理循环和 promise ?

javascript - React 组件 DOM 未更新

javascript - 为什么光标不显示在 Internet Explorer 的输入字段中?

javascript - 为什么 Promise 的 `then()` 处理程序会立即执行?

Javascript Promise 返回值

javascript - 如何调用根据 promise 结果返回 promise 的函数?