提问人:WhatTheWhat 提问时间:9/23/2023 最后编辑:WhatTheWhat 更新时间:9/26/2023 访问量:86
同步运行 asnyc 函数
Running asnyc function synchronously
问:
我是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 期望它们隔行扫描的位置
答:
0赞
WhatTheWhat
9/26/2023
#1
因为调用是我无权访问的异步回调,所以我不能。答案是解除应用程序存储任何状态的责任,将任何数据库对象的创建推送到上游的前端或其他服务。这仅意味着 UI 必须进行 2 次连续调用,而不是一次。await
评论
0赞
ggorlen
9/26/2023
“因为调用是我无权访问的异步回调,所以我不能等待它”。对此的正常解决方案是改用库的异步 API(假设它是一个相当现代的库),承诺回调以便您可以等待它,或者如果库没有基于 promise 的接口,则转储库,您可以找到一个现代替代方案。
评论
const response = await axios.get(...);
await
onUploadCreate
await