javascript - 如何正确处理父异步调用中的一系列异步调用
问题描述
我有一个用例,我想进行异步调用(认为它类似于 ajax),然后在该调用的成功块中,我想使用父调用生成的 id 在循环中进行一系列异步调用。我的要求是:
- 我在哪里放置显示成功吐司的代码?目前我把它放在成功块内的for循环之后,但它有一个问题,它会在子异步调用完成之前被执行,因为for循环不会等待调用并且会立即执行并且代码会去到展示成功的祝酒词。
- 如果任何一个子调用失败,则不应发生进一步的调用(从效率的角度来看这更多),而且在这种情况下,我应该能够删除创建的父记录,以便如何处理也?提前致谢!
示例代码片段:
asyncCallA(inputId)
.then(output => {
// inputIdsForChildCalls is the list of inputIds for child async
// calls
inputIdsForChildCalls = [do something with output]
for (let i = 0; i < inputIdsForChildCalls.length; i++) {
asyncCallB(inputIdsForChildCalls[i])
.then(output => {
// do something
})
.catch(error => {
// do something with error
});
}
showSuccessToast("Records created successfully!");
})
.catch(error => {
// do something with error
});
解决方案
因为听起来你想asyncCallB()
连续运行,所以如果其中一个失败,你可以避免任何额外的调用,那么这将最容易使用async/await
.
为此,您必须将包含函数标记为async
允许使用await
. 然后,您可以使用await
来对异步操作进行排序:
async function someFunc(inputId) {
try {
let output = await asyncCallA(inputId);
// inputIdsForChildCalls is the list of inputIds for child async
// calls
let inputIdsForChildCalls = [do something with output]
for (let childId of inputIdsForChildCalls) {
let childResult = await asyncCallB(inputIdsForChildCalls[childId]);
// process child result here
// errors in asyncAllB() will have gone to the catch(e) statement below
}
showSuccessToast("Records created successfully!");
} catch(e) {
// handle error here
// throw an error here if you want the caller to be able to see the error
}
}
为了可能获得更快的性能,您可以asyncCallB()
如下所示并行运行您的操作,但所有asyncCallB()
调用都将运行,即使第一个调用有错误(因为它们都是并行启动的):
async function someFunc() {
try {
let output = await asyncCallA(inputId);
// inputIdsForChildCalls is the list of inputIds for child async
// calls
let inputIdsForChildCalls = [do something with output]
let allResults = await Promise.all(inputIdsForChildCalls.map(childId => {
return asyncCallB(childId);
}));
// process allResults array here
// errors will have gone to the catch(e) statement below
showSuccessToast("Records created successfully!");
} catch(e) {
// handle error here
}
}
推荐阅读
- python - 在 Airflow 中具有依赖项的导入
- java - 在构造函数中初始化 arrayList 或 map 是好的做法吗?
- node.js - Angular中的Textarea不显示文本
- android - 如何调用项目到项目?
- r - 创建 .Renviron 中设置的用户库目录的最佳方法是什么?
- c++ - 如何编写一个必须检索两个时间戳之间的记录的mongocxx查询?
- cakephp - CakePHP 3 - 单元测试 tearDown() 无法删除文件:'资源暂时不可用'
- datagrid - 如何防止数据网格中的交替行选择?
- php - Laravel 第二个数据库连接按外键值选择过滤
- c# - SQL Server 的 ODBC 连接字符串中的令牌顺序是否重要?