提问人:Jeffrey Bentley 提问时间:4/12/2023 最后编辑:halferJeffrey Bentley 更新时间:4/19/2023 访问量:52
使用来自 Node/Express 中间 API 的多个 API 调用,尝试使用 promise.all()
Working with multiple API calls from a Node/Express intermediate API, trying to use promise.all()
问:
在这个项目中,我发现了我的理解中的各种差距。我正在构建一个中间 API 服务器。一些端点获取一组信息,然后对每条信息进行外部调用,然后对响应进行一些操作,最终需要在完成所有操作后发送响应。
我通常一次处理一个电话,并认为我对 Async Await 有很好的掌握。三年前,我使用 Promise.all() 进行一些并行调用,但这是一个时代,这并不完全是以相同的方式翻译。我还尝试使每个步骤都在事物上并链接 .then()s,但是我的一些函数没有看到异步/不会触发 .我看过的所有文档都让我走到了一半,但我仍然卡住了。.then()
const createUserDir = async (req, res) =>{
// make User Directory
fs.mkdir(path.join(__dirname, `../Users/${req.body.userID}`), { recursive: true },(err)=>{
if (err) {
return console.error(err);
}
getAllAssetImages(req.body.assets, req.body.config, req.body.userID, res)
})
}
const getAllAssetImages =async (assets, config, userID, response)=> {
try {
const allAssets = await Promise.all(
assets.map(asset => (
// utils.getAsset is an axios call to get a file, this works
utils.getAsset(asset, config)
.then(res => fs.mkdir(path.join(__dirname, `../Users/${userID}/${asset.assetId}`),
()=>fs.writeFile(path.join(__dirname, `../Users/${userID}/${asset.assetId}/${asset.assetId}.pptx`), res.data, {encoding: 'binary'}, async (err) => {
if (err){
console.log(err.code)
} else {
console.log("File written successfully")
//convertPPTS.convertPPTS is an async function that uses ppt-png npm package: works
convertPPTS.convertPPTS([path.join(__dirname,`../Users/${userID}/${asset.assetId}/${asset.assetId}.pptx`)],path.join(__dirname,`../Users/${userID}/${asset.assetId}/`))
}
}
))
)
)))
.then(()=>{
console.log('please log at the end')
response.send({status:200, body:'assets available!'})
})
console.log('all the promises', allAssets)
} catch (err){
throw Error(err)
}
}
router.post('/', (req,res) => {
createUserDir(req, res)
.then(()=>{console.log('all assets written')})
})
export default { router }
它通常会完成获取,写入转换三个文件中的 2 个,然后说它已经完成,然后在它尝试转换尚未存在的文件时抛出错误。
答:
0赞
Jeffrey Bentley
4/13/2023
#1
我做的最重要的事情是删除了 .then() 和 await promise 的混合,倾向于 promise 和 async await。我相信,通过允许其中一些并行运行,并改变正在等待的内容,还有优化的空间。
const createUserDir = async (req) => {
let { assets, userID, SP } = req.body;
fs.mkdir(path.join(__dirname, `../Users/${req.body.userID}`), { recursive: true }, (err) => {
if (err) {
console.error(err.message)
return (err);
}
}
);
await getAllAssetImages(assets, SP, userID);
};
const getAllAssetImages = async (assets, config, userID) => {
try {
await Promise.all(
assets.map(async (asset) => {
let res = await showpadUtils.getAsset(asset, config);
await new Promise((resolve, reject) =>
fs.mkdir( path.join(__dirname, `../Users/${userID}/${asset.assetId}`), () => (
fs.writeFile(path.join(__dirname, `../Users/${userID}/${asset.assetId}/${asset.assetId}.pptx`),
res.data,
{ encoding: "binary" },
async (err) => {
if (err) {
console.log(err.code);
} else {
console.log("File written successfully");
resolve(
convertPPTS.convertPPTS(
[
path.join(__dirname, `../Users/${userID}/${asset.assetId}/${asset.assetId}.pptx`),
],
path.join(__dirname, `../Users/${userID}/${asset.assetId}/`)
)
);
}
}
)
)
)
);
})
);
console.log("please log at the end");
} catch (err) {
throw Error(err);
}
};
router.post("/", async (req, res) => {
await createUserDir(req);
console.log("all assets written");
res.send({ status: 200, body: "assets available!" });
});
评论
0赞
Bergi
4/13/2023
不要使用函数作为回调 - 你没有做任何事情,即使你这样做了,你也应该只承诺而不是包装业务逻辑。此外,而不是 do call ,并且 是没有意义的,应该省略。async
fs.writeFile
await
writeFile
if (err) { console.log(err.code); }
reject
} catch (err) { throw Error(err); }
0赞
Bergi
4/13/2023
你不是在等../Users/${req.body.userID} 完成。fs.mkdir(path.join(__dirname,
), …)
评论
fs.mkdir
fs.writeFile
fs/promises
fs