认识异步与同步
在JavaScript中,理解异步(Asynchronous)和同步(Synchronous)编程是至关重要的,因为它们直接影响了代码的执行方式和性能。
同步编程
定义:同步编程意味着代码的执行顺序与书写顺序完全一致。即,每一行代码执行完成后,才会执行下一行代码。如果当前操作依赖于某个耗时任务(如网络请求、文件读写等),则整个程序会等待该任务完成后再继续执行。
特点:
- 顺序执行
- 易于理解和调试
- 可能导致性能问题,特别是处理耗时任务时
示例:
javascript
console.log('开始');
// 假设这是一个耗时的操作,但为了示例,我们直接用setTimeout模拟
setTimeout(() => {
console.log('耗时任务完成');
}, 2000); // 2秒后执行
console.log('结束'); // 这行会立即执行,不会等待上面的setTimeout完成
1
2
3
4
5
6
2
3
4
5
6
提示
setTimeout()
函数是 JavaScript 中的一个内置函数,用于在指定的延迟时间后执行一个函数或指定的代码片段。这个函数接受两个参数:第一个参数是要执行的函数或要执行的代码(作为字符串,但出于安全和性能考虑,不推荐使用字符串),第二个参数是延迟的时间(以毫秒为单位)。
在同步编程中,结束
会先于耗时任务完成
打印出来。
异步编程
定义:异步编程允许程序在等待耗时任务完成时,继续执行后续的代码。当耗时任务完成后,会通过回调函数、Promises、async/await等方式通知程序处理结果。
特点:
- 非阻塞执行
- 提高程序性能,尤其是处理多个耗时任务时
- 代码逻辑可能较为复杂,尤其是多层嵌套时
示例(使用Promises):
javascript
console.log('开始');
// 假设fetchData是一个返回Promise的函数,模拟异步数据请求
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('数据加载完成');
}, 2000);
});
}
fetchData().then(data => {
console.log(data); // 异步操作完成后执行
}).catch(error => {
console.error('出错了:', error);
}).finally(() => {
console.log('无论成功或失败,都会执行');
});
console.log('结束'); // 这行会立即执行,不会等待fetchData完成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
在这个异步示例中,结束
会先于数据加载完成
打印出来,而数据加载完成
会在2秒后打印,此时fetchData
的Promise已经解决。
async/await(基于Promises的语法糖)
async/await
使得异步代码看起来和同步代码几乎一样,极大地提高了代码的可读性和可维护性。
示例:
javascript
async function fetchAndLogData() {
console.log('开始');
try {
const data = await fetchData(); // 等待Promise解决
console.log(data);
} catch (error) {
console.error('出错了:', error);
} finally {
console.log('无论成功或失败,都会执行');
}
console.log('结束'); // 在数据加载完成后执行
}
fetchAndLogData();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
在这个async/await
示例中,代码的执行顺序看起来像是同步的,但实际上它是异步的。结束
会在数据加载完成
之后打印出来。