同步运行 asnyc 函数

Running asnyc function synchronously

提问人:WhatTheWhat 提问时间:9/23/2023 最后编辑:WhatTheWhat 更新时间:9/26/2023 访问量:86

问:

我是JS的新手。我正在使用具有异步回调的第三方库。问题是,在处理下一个回调之前,我需要完整地运行该函数。我正在使用名为 tus.io 的上传协议,需要一次处理一个上传。

async onUploadCreate(req, res, uploadMetadata) {

    /* I need to check the metadata is valid by using an internal js file */
    //...

    /* Then I need to check the user is logged in by calling a third-party endpoint using axios*/
    //...

    /* Then I check the Mongo db for existing uploadId
    //...
        // if it's not there, create some entries in another db and add the uploadId to mongo
        //If it is there, get some IDs in mongo, which I append to another db
}

正如你所看到的,我需要做很多事情。我这样做是因为在tus中,没有上传会话的概念;每个文件都是独立上传的。我一直在通过一次上传一个文件来测试它。当我使用多个文件时,它到处都是。

有没有办法在 JavaScript 中实现这一点?我知道这可能会对性能产生影响,因此我愿意就如何实现这一目标提出建议。


编辑:根据评论建议,我尝试等待使用 axios 和 mongo lib 的函数,但这似乎没有区别。这是完整的函数调用:

async onUploadCreate(req, res, upload) {
        /* Check the metadata */
        const {ok, expected} = await common.validateMetadata(upload);
        if (!ok) {
            const body = `Expected "${expected}" in "Upload-Metadata" but received "${upload.metadata}"`;
            throw {status_code: 500, body};
        } else
        logger.info(`Metadata is ok!`);

        /* Check the user is logged in */
        const userAuthorised = await catalogue.getSession(upload.metadata.userSession);
        if (!userAuthorised) {
            const body = `User not authorised`;
            logger.info(`User with session id: "${upload.metadata.userSession}" not authed`);
            throw {status_code: 401, body};
        } else
            logger.info(`User with session id: "${upload.metadata.userSession}" is logged in`);

        /* Create the items in the catalogue and mongo db for tracking upload session*/
        // check the mongo db for existing uploadId
        const result =  await mongo.getUploadIdInDB(upload.metadata.uploadId);
        if (result == null) {
            logger.info(`Upload ID: "${upload.metadata.uploadId}" not found in mongodb`)
            // create a dataset in catalogue
            let dataset = await catalogue.createDataset(upload.metadata);
            // then create the datafiles in catalogue
            let datafile = await catalogue.createDatafile(dataset, upload.id, upload.size, upload.metadata);
            // then add the id in mongo
            await mongo.createUpload(upload.metadata, dataset, datafile)
        }
        else {
            logger.info(`Upload ID: "${upload.metadata.uploadId}" found in mongodb!`)
            // create a new datafile to go this dataset
            let datafile = await catalogue.createDatafile(result.datasetId[0], upload.id, upload.size, upload.metadata);
            // then add the id of the nre datafile to the upload entry in mongo
            await mongo.appendToUpload( result.datasetId, datafile)
        }
        logger.info(`Done processing upload file`)
        return res;
    },

例如,我得到的输出是:

info: Metadata is ok! {"service":"upload-service"}
info: Metadata is ok! {"service":"upload-service"}
info: User with session id: "bb6190fb-369b-406e-8b64-b38bef644df6" is logged in {"service":"upload-service"}
info: User with session id: "bb6190fb-369b-406e-8b64-b38bef644df6" is logged in {"service":"upload-service"}
....

id 期望它们隔行扫描的位置

javascript 异步 async-await promise tus

评论

1赞 epascarello 9/23/2023
所以使用 await 阅读文档const response = await axios.get(...);
5赞 Bergi 9/23/2023
不可以,不可能同步运行异步函数。但是,按顺序运行多个异步步骤是微不足道的 - 只是它们。await
0赞 WhatTheWhat 9/23/2023
谢谢,我尝试过使用 await 但没有运气,但是我还没有尝试将所有代码包装在 await / async 函数中。也许那会起作用?
0赞 WhatTheWhat 9/23/2023
我尝试将整个过程包装在我等待的异步函数中,但这并没有区别
1赞 trincot 9/23/2023
改编后的代码看起来不错,但现在问题出在你尚未共享的调用代码部分。显然你连续调用了几次,但在这样的调用之前,你也需要使用,显然你没有这样做。onUploadCreateawait

答:

0赞 WhatTheWhat 9/26/2023 #1

因为调用是我无权访问的异步回调,所以我不能。答案是解除应用程序存储任何状态的责任,将任何数据库对象的创建推送到上游的前端或其他服务。这仅意味着 UI 必须进行 2 次连续调用,而不是一次。await

评论

0赞 ggorlen 9/26/2023
“因为调用是我无权访问的异步回调,所以我不能等待它”。对此的正常解决方案是改用库的异步 API(假设它是一个相当现代的库),承诺回调以便您可以等待它,或者如果库没有基于 promise 的接口,则转储库,您可以找到一个现代替代方案。