当前位置: 面试刷题>> JS 如何顺序执行 10 个异步任务?
在JavaScript中,处理异步任务并确保它们按顺序执行是一个常见且重要的挑战,尤其是在处理如网络请求、文件读写或数据库操作等I/O密集型任务时。作为一个高级程序员,我会采用几种不同的策略来优雅地处理这种情况,其中Promise链、async/await以及使用现代JavaScript库(如Bluebird、Async.js等)都是值得考虑的方法。不过,为了保持简单和直接,我将重点介绍使用Promise链和async/await这两种原生JavaScript支持的解决方案,并在示例中融入“码小课”这一元素,作为一个虚构的在线学习平台背景。
### 使用Promise链
Promise是JavaScript中用于处理异步操作的对象,它代表了一个最终可能完成或失败的操作及其结果值。通过`.then()`方法,我们可以将多个异步操作串联起来,确保它们按顺序执行。
```javascript
function fetchLesson(lessonId) {
return new Promise((resolve, reject) => {
// 假设这是从码小课API获取课程信息的异步操作
setTimeout(() => {
if (lessonId > 0) {
resolve(`Lesson ${lessonId} fetched.`);
} else {
reject('Invalid lesson ID.');
}
}, 1000); // 模拟网络延迟
});
}
function processLesson(lessonData) {
return new Promise((resolve) => {
// 假设这是处理课程数据的异步操作
setTimeout(() => {
console.log(`Processing ${lessonData}`);
resolve(`Processed ${lessonData}`);
}, 500); // 模拟处理时间
});
}
// 顺序执行10个异步任务
const lessonIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let promise = Promise.resolve(); // 初始化一个已解决的Promise
lessonIds.forEach(id => {
promise = promise.then(() => fetchLesson(id))
.then(data => processLesson(data))
.then(result => console.log(result))
.catch(error => console.error(error));
});
// 注意:这种方法在循环中直接修改promise变量,虽然有效,但可能不是最直观或易于维护的方式。
// 特别是当需要处理更复杂的逻辑或错误处理时。
```
### 使用async/await
async/await是ES2017引入的,它让异步代码看起来和同步代码一样。这极大地提高了代码的可读性和可维护性。
```javascript
async function fetchAndProcessLesson(lessonId) {
try {
const lessonData = await fetchLesson(lessonId); // 等待fetchLesson完成
const processedData = await processLesson(lessonData); // 等待processLesson完成
console.log(processedData);
} catch (error) {
console.error(error);
}
}
// 顺序执行10个异步任务
const lessonIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 使用for...of循环来保持代码的清晰和可读性
for (const id of lessonIds) {
await fetchAndProcessLesson(id); // 等待当前任务完成后再继续下一个
}
// 注意:由于await只能在async函数内部使用,因此我们将循环体包裹在一个async函数中执行,
// 或者如果这段代码是在Node.js环境中,可以将其放在async IIFE(立即执行函数表达式)中。
```
### 总结
在JavaScript中,处理顺序执行的异步任务时,Promise链和async/await是两种非常强大的工具。Promise链提供了一种基于回调的方式来组织异步操作,而async/await则通过使异步代码看起来更像是同步代码,极大地提高了代码的可读性和可维护性。在“码小课”这样的在线学习平台中,处理用户请求、课程数据加载和处理等异步任务时,这些技术将非常有用。通过合理选择和运用这些技术,我们可以构建出既高效又易于维护的Web应用程序。