gpt4 book ai didi

javascript - 如何从异步函数返回一个 Promise?

转载 作者:行者123 更新时间:2023-11-29 17:46:06 25 4
gpt4 key购买 nike

当我尝试从异步函数返回一个 promise 时,无法区分返回的 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(/*...*/)时,首先是给定数据的给定ID的metaData,经过一小段时间后,等待完整的 singleData 是预期的。

但这有点骇人听闻。

克服这种情况的预期方法是什么?

附言:当我尝试返回一个用 promise 解决的 promise 时,也会出现这个问题。

最佳答案

是的,不幸的是 JS promises 不是代数的并且 you cannot fulfill a promise with another promise .没有办法解决这个问题(除了不使用 native promise ,并且不使用 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 singleDataPromise,这可能会导致未处理的拒绝问题。

(可能更好)替代方法是重构您的函数,这样您就不会在使用(即等待)它们之前创建任何 promise ,就像@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);
}

关于javascript - 如何从异步函数返回一个 Promise?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49541574/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com