嵌套的异步承诺:如何知道它们何时全部解决?
Nested, asynchronous promises: how to know when they're all resolved?
我正在通过网络应用进行一些 api 调用。首先,我要获取合作伙伴的详细信息(一组酒店)。这个合作伙伴有一些属性。对于这些属性中的每一个,我都需要得到它们的房间;然后对于这些房间中的每一个,我需要获得他们的可用性和预订。
我想异步执行所有这些调用(即,一旦我获得 属性 的房间信息,我就可以获得他们的预订和可用性,而无需等待所有属性的详细信息)。
我想知道何时加载所有内容。下面是使用超时模拟 api 调用的简化代码。
我试图将每个新承诺推送到一个数组中,并在此数组上使用 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();
我希望 "all finished" 最后显示在控制台中。相反,它会在 "getPartner finished"
之后立即显示
编辑:这是我用计数器尝试过的:
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
没有 return 任何东西,但你应该 return 一个数组 -- 以提供给 Promise.all
.
在每个你有多个承诺的情况下使用Promise.all
Return 当你需要在 then
回调中链接一个承诺时
这是它的工作原理:
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');
});
});
}
我正在通过网络应用进行一些 api 调用。首先,我要获取合作伙伴的详细信息(一组酒店)。这个合作伙伴有一些属性。对于这些属性中的每一个,我都需要得到它们的房间;然后对于这些房间中的每一个,我需要获得他们的可用性和预订。 我想异步执行所有这些调用(即,一旦我获得 属性 的房间信息,我就可以获得他们的预订和可用性,而无需等待所有属性的详细信息)。 我想知道何时加载所有内容。下面是使用超时模拟 api 调用的简化代码。
我试图将每个新承诺推送到一个数组中,并在此数组上使用 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();
我希望 "all finished" 最后显示在控制台中。相反,它会在 "getPartner finished"
之后立即显示编辑:这是我用计数器尝试过的:
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
没有 return 任何东西,但你应该 return 一个数组 -- 以提供给Promise.all
.在每个你有多个承诺的情况下使用
Promise.all
Return 当你需要在
then
回调中链接一个承诺时
这是它的工作原理:
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');
});
});
}