首先,理解 async 函数的基本概念:声明一个函数为 async 函数后,该函数会隐式地返回一个Promise对象,并且可以在其内部使用 await 关键字等待 Promise 对象的结果。例如:
javascript
async function getData(id) {
const response = await fetch(`https://api.example.com/data/${id}`);
return response.json();
}
然后,在涉及到 For 循环的情况下,我们可能会希望遍历数组并逐个执行异步任务。直接将 `async/await` 和常规for循环结合起来可能并不会按预期顺序执行——所有异步操作将会同时开始而非串行进行:
javascript
const ids = [1,2,3];
(async () => {
for (let id of ids) {
let data = awaitgetData(id);
console.log(data); // 这里不会按照ID升序打印数据
}
})();
上述示例虽然每个迭代都在等待前一次获取的数据完成后再继续,但各个请求之间并没有实现真正的“序列化”(即下一个请求必须等到当前请求完成后才发起)。
为了确保一系列异步操作严格按照指定次序依次运行,可以采用递归或封装成一个新的 promise chain等方式来解决这个问题:
javascript
// 使用递归来保证每次只在一个异步操作结束后再启动下一轮循环
function processSequentially(ids, index=0){
if(index >= ids.length)
return;
let currentId = ids[index];
(async ()=>{
let data = await getData(currentId);
console.log(data);
// 当前操作结束之后触发下一步骤
processSequentially(ids, ++index);
})();
}
processSequentially([1,2,3]);
// 或者利用 then 方法手动构建promise链以达到相同效果:
ids.reduce((p,id)=>{
return p.then(()=>{
return getData(id).then(console.log);
});
}, Promise.resolve());
以上就是在JavaScript中如何正确结合运用 Async/Await 以及 For 循环的一个详细解读。通过合理设计程序结构及巧妙借助各种方法如递归或者 Promises 链的形式,我们可以高效有序地管理多个依赖于时间先后关系的异步任务。