当我尝试从异步函数返回 Promise 时,无法区分返回的 Promise 和函数的状态。
我认为,最简单的解决方案是将要返回的承诺放在数组中。下面是一个愚蠢的例子,但我希望它能说明问题:
function loadMetaData(id) {/*...*/} // Returns Promise<MetaData>
function loadSingleData(name) {/*...*/} // Returns Promise<SingleData>
async function startLoadingSingleData(id, object) {
const metaData = object.metaData = await loadMetadata(id);
const singleDataPromise = loadSingleData(metaData.dataToLoad);
singleDataPromise.then(metaData => object.metaData = metaData);
return [singleDataPromise];
}
async function logData(id) {
const object = new SomeUsefulClassWhatTakesAdvantageOfMetadataProp();
somePromise = (await startLoadingSingleData(id))[0];
// Now metadata surely loaded, do something with it
console.log(object.metaData);
// But somedata will be loaded only in future
somePromise.then(singleData => console.log(singleData));
// And maybe: (depends of use-case)
await somePromise;
}
执行时logData(/*...*/)
,首先是metaData
短时间后,给定数据的给定 ID,并稍等片刻后,完整的singleData
是期待。
但这有点hackish。
克服这种情况的预期方法是什么?
附:
当我尝试返回一个由承诺解决的承诺时,也会出现这个问题。
是的,不幸的是 JS 承诺不是代数的并且你不能用另一个承诺来履行一个承诺 https://stackoverflow.com/q/32168194/1048572。没有办法解决这个问题(除了不使用本机承诺,并且不使用async
/await
).
最简单和最常见的解决方案确实是使用包装对象。这很自然地解决你的问题:
// takes an id, returns a Promise<{metaData: Data, singleDataPromise: Promise<Data>}>
async function startLoadingSingleData(id) {
const object = new SomeUsefulClassWhatTakesAdvantageOfMetadataProp();
object.metaData = await loadMetadata(id);
// ^^^^^
object.singleDataPromise = loadSingleData(object.metaData.dataToLoad);
// ^ no await here
return object;
}
async function logData(id) {
const object = await startLoadingSingleData(id));
// Now metadata surely loaded, do something with it
console.log(object.metaData);
// But some singleData will be loaded only in future
const singleData = await object.singleDataPromise;
console.log(singleData);
}
请注意,如果您的代码中有异常并且您永远无法处理,这可能会导致未处理拒绝的问题await
the singleDataPromise
.
(可能更好)的替代方案是重组您的函数,以便您在使用(即等待)它们之前不会创建任何承诺,就像 @Paulpro 也建议的那样。所以你只需编写一个严格顺序的函数
async function logData(id) {
const object = new SomeUsefulClassWhatTakesAdvantageOfMetadataProp();
object.metaData = await loadMetadata(id);
// Now metadata surely loaded, do something with it
console.log(object.metaData);
// But some singleData will be loaded only in future
object.singleData = await loadSingleData(object.metaData.dataToLoad);
console.log(object.singleData);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)