javascript - for循环内的异步回调
问题描述
var a = ['url1', 'url2', 'url3'];
var op = [];
cb = (callback) => {
for (var i = 0; i < a.length; i++) {
gtts.savetos3(`${a[i]}.mp3`, a[i], 'ta', function(url) {
console.log(url['Location']);
op.push(url['Location']);
});
}
callback()
}
cb(() => {
console.log(op);
})
在上面的代码中,gtts.savetos3是一个异步函数。完成数组中每个元素的执行需要花费大量时间。由于异步功能,我无法在op数组中打印完整的 url 数组,因为它会打印一个空数组.
gtts.savetos3函数使用正确的 url 调用给定的回调,以便我可以使用打印输出,console.log
但是在循环时我搞砸了。
我的问题是
- 如何使回调函数仅在所有数组元素执行后才被gtts.savetos3函数处理。
- 我们可以在没有Promise.all或没有Promise的情况下仅使用回调来解决上述问题吗?
提前致谢 ...!
解决方案
您可以保留一个计数器并在方法的回调中增加它,
done
仅当计数器达到数组的长度时才调用您的回调。
cb = (done) => {
let counter = 0;
for (let i = 0; i < a.length; i++) {
gtts.savetos3(`${a[i]}.mp3`, a[i], 'ta', function (url) {
console.log(url['Location']);
op.push(url['Location']);
++counter;
if (counter == a.length) {
done();
}
});
}
}
cb(() => {
console.log(op);
})
这只是在没有Promises
或任何第三方模块的情况下解决问题的一种方法,而不是优雅或正确的方法。
如果您想坚持回调并且可以使用第三方模块,请查看 Async
waterfall method
。如果您正在使用
aws-sdk
'ss3 put object
,那么 sdk 也已经提供了一种承诺方法,您可以简单地附加您的方法.promise
来获得相同的方法。要解决 Promise 的问题,只需将包装器更改为异步函数即可。
async savetos3(...parametres) {
//Some implementation
let res = await S3.putObject(....params).promise();
//Some implementation
}
cb = Promise.all(a.map(name => savetos3(`${name}.mp3`, name , 'ta')));
cb.then(() => {
console.log(op);
})
推荐阅读
- r - 如何通过函数输入将协变量添加到 cox 模型
- python - Access and modify weights sent from client on the server tensorflow federated
- python - Specify max delimiter with delim_whitespace, read_csv
- reactjs - Permissions-Policy 标头出错:无法识别的功能:'interest-cohort'
- java - 使用自定义主键保存 Spring Boot JPA
- python - 我想从另一个表(熊猫、jupyter notebook、python)覆盖我表的两列
- python - 如何在 Python 中进行均值和分组?
- django - 注册用户不会出现在管理面板中
- javascript - 无法使用 GoogleAuthProvider 在 Firebase 9.1.3 中导入提供程序
- mongodb - 可以在 Mac 上正确启动 MongoDB