如何从异步函数返回Promise? [英] How to return a Promise from async function?

查看:432
本文介绍了如何从异步函数返回Promise?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试从异步函数返回promise时,不可能区分返回的Promise和函数的状态。

When I try to return a promise from an async function, it's impossible to distinguish the status of the returned Promise and the function.

我认为,最简单的解决方案是将承诺返回到数组中。以下是一个愚蠢的示例,但我希望它能演示该问题:

I think, the simplest solution is to put the promise to be returned in an array. The following is a stupid example, but I hope it demonstrates the problem:

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 是预期的。

When executing logData(/*...*/), first the metaData of the given ID of the given data after a short period, and after a little waiting the full singleData is expected.

但这有点黑。

什么

PS .:
当我尝试返回以承诺解决的Promise时,也会发生此问题。 / p>

PS.: This problem occurs too, when I try to return a Promise which resolves with the promise.

推荐答案

您的问题是 startLoadingSingleData 的职责过多。它负责加载元数据并触发单个数据的加载。

Your problem is that startLoadingSingleData has too many responsibilities. It is responsible for both loading the metadata and triggering loading of singledata.

您的 logData 函数使用等待startLoadingSingleData(id)作为确保元数据可用的一种方式,这似乎不太直观。 startLoadingSingleData(id)返回一个Promise会在元数据加载时解析,这并不明显,这对于编码人员第一次查看它是非常混乱的(或几个月后,您自己)。代码应尽可能自我记录,这样您就无需在每行注释中都进行解释。

Your logData function uses await startLoadingSingleData(id) as a way to make sure that metadata is available, which does not seem very intuituve. It is not obvious that startLoadingSingleData(id) returns a Promise that resolves when the metadata has loaded, and would be quite confusing for a coder looking at it for the first time (or yourself after a few months). Code should be self-documenting as much as possible so that you don't need to explain every line with comments.

我的建议是完全删除 startLoadingSingleData 函数,只需在 logData 内部执行此操作:

My recommendation is to completely remove the startLoadingSingleData function and just do this inside logData:

async function logData(id) {
    const metaData = await loadMetadata(id);
    console.log(metaData);

    const singleData = await loadSingleData(metaData.name);
    console.log(singleData);
}

或者如果您不希望logData 等待 SingleData承诺:

or if you don't want logData to await the SingleData Promise:

async function logData(id) {
    const metaData = await loadMetadata(id);
    console.log(metaData);

    loadSingleData(metaData.name).then( singleData => {
        console.log(singleData);
    } );
}

如果您真的想继续使用函数 startLoadingSingleData 相反,我认为您应该使它返回包含两个Promise的数组或对象:

If you really want to keep using the function startLoadingSingleData instead then I think you should make it return an array or an object containing two Promises:

function startLoadingSingleData(id) {
    const metaDataLoaded = loadMetadata(id);
    const singleDataLoaded = metaDataLoaded.then(
      metaData => loadSingleData(metaData.dataToLoad)
    );

    return { metaDataLoaded, singleDataLoaded };
}

然后您的用法如下:

async function logData(id) {
    const { metaDataLoaded, singleDataLoaded } = startLoadingSingleData(id);

    const metaData = await metaDataLoaded;
    console.log(metaData);

    const singleData = await singleDataLoaded;
    console.log(singleData);
}

这篇关于如何从异步函数返回Promise?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆