node.js - 带有等待异步问题的循环迭代
问题描述
我有一个带有两个等待异步函数的循环。我希望第二个函数(F2)会在第一个等待函数(F1)完成后触发。但是循环继续,甚至没有启动 F2。F2 仅在 F1 异步函数触发后触发。
我提供了跟踪功能来跟随流程。
for (let i=0; i<5; i++){
const S3result = (async () => {
try {
console.log ('starting await promise 1' );
params.Key = '012/' + 'bob1' + i.toString();
await promiseS3(s3, params);
console.log ('complete 1st upload');
params.Key = '012/' + 'bob2' + i.toString();
console.log ('starting await promise 2' );
await promiseS3(s3, params);
console.log('completed 2nd upload');
} catch (e) {
console.log (e)
}
})()
const promiseS3 = (s3object,params) => {
return new Promise((resolve, reject) => {
console.log ('start s3 Object promise function');
s3object.upload(params, function(s3Err, data) {
if (s3Err) reject ('bad S3 call')
console.log(`File uploaded successfully at ${data.Location}`)
resolve (data);
});
})
}
我预计 F1 会开火,等待,然后在 F1 完成后让 F2 开火。
这是输出:
启动await promise 1 start s3 对象promise函数 启动await promise 1 start s3 对象promise函数 启动await promise 1 start s3 对象promise函数 启动await promise 1 start s3 对象promise函数 启动await promise 1 start s3 函数后对象promise函数 文件上传成功在https://filesafe-beta.s3.us-west-1.wasabisys.com/012/bob14 完成第一次上传开始等待承诺 2 开始 s3 对象承诺功能文件在https://filesafe-beta.s3 成功上传。 us-west-1.wasabisys.com/012/bob11 完成第一次上传开始等待承诺 2 开始 s3 对象承诺功能文件在https://filesafe-beta.s3.us-west-1.wasabisys.com/012成功上传/鲍勃10 完成第 1 次上传开始等待承诺 2 开始 s3 对象承诺功能文件成功上传到https://filesafe-beta.s3.us-west-1.wasabisys.com/012/bob12 完成第一次上传开始等待承诺 2 开始 s3 对象承诺function 文件在https://filesafe-beta.s3.us-west-1.wasabisys.com/012/bob13上传成功 完成第一次上传开始等待承诺 2 开始 s3 对象承诺功能文件在https://filesafe-成功上传beta.s3.us-west-1.wasabisys.com/012/bob22 完成第二次上传 文件上传成功在https://filesafe-beta.s3.us-west-1.wasabisys.com/012/bob21 完成第二次上传文件在https://filesafe-beta.s3.us-west-1.wasabisys.com/012/bob23成功上传 完成第二次上传 文件成功上传至https://filesafe-beta.s3.us-west-1.wasabisys.com/012/bob24 完成第二次上传 文件成功上传至https://filesafe-beta.s3.us-west -1.wasabisys.com/012/bob20 完成第二次上传
解决方案
你必须把async
上面的for
循环,而不是for
循环内。请记住,一旦async
函数命中 an await
,它就会立即返回一个 Promise。因此,按照您的结构方式,您根本不会暂停for
循环。您只是在创建一个异步函数并在循环的每次迭代中一遍又一遍地执行它,而没有人关注async
函数返回的承诺。
所以,你可以这样做:
const S3result = (async () => {
for (let i=0; i<5; i++){
try {
console.log ('starting await promise 1' );
params.Key = '012/' + 'bob1' + i.toString();
await promiseS3(s3, params);
console.log ('complete 1st upload');
params.Key = '012/' + 'bob2' + i.toString();
console.log ('starting await promise 2' );
await promiseS3(s3, params);
console.log('completed 2nd upload');
} catch (e) {
console.log (e)
}
}
})()
此外,S3result
将是一个承诺,当for
循环和其中的所有await
语句都完成时,该承诺将被解决。
或者,像这样,您实际上是在正确的循环视图中函数await
的结果,所以它实际上会暂停循环(这个循环本身必须在一个函数中才能使用,所以这里可能没有理由使用 IIFE . 让循环像第一个选项一样直接管理语句可能更简单:async
for
for
for
async
await
for
await
async function someFunction() {
for (let i=0; i<5; i++){
await (async () => {
try {
console.log ('starting await promise 1' );
params.Key = '012/' + 'bob1' + i.toString();
await promiseS3(s3, params);
console.log ('complete 1st upload');
params.Key = '012/' + 'bob2' + i.toString();
console.log ('starting await promise 2' );
await promiseS3(s3, params);
console.log('completed 2nd upload');
} catch (e) {
console.log (e)
}
})();
}
}
推荐阅读
- python - 将 3D 数组转换为 pandas 面板数据
- css - 为什么没有填充,尽管我在 react native 中使用带有 `space-between` 的 flexbox 时设置了它?
- function - Same PowerShell Code Works as Seperate File, Not as Function
- spring - 如何在@ExceptionHandler 方法中检索 POST 请求对象/参数
- python - Python将数据框转换为逗号分隔的行
- mysql - mySql Insert X Select Y 失败,而 Select Y 成功并且 Insert X "literal Y" 也成功
- microsoft-teams - Microsoft Teams App Studio - 无法打开清单编辑器和卡片编辑器
- box2d - 使玩家在特定位置重生的问题
- c# - 表行中的 asp-route 未传递 id
- php - 做一个 Preg_match 然后单独检查每个选项