- 回调函数(Callback)
- 特点:通过将一个函数作为参数传递给另一个异步操作的函数,当异步操作完成时,调用这个回调函数来处理结果。这种方式简单直接,但如果存在多个嵌套的异步操作,会导致回调地狱(Callback Hell),代码可读性和维护性变差。
- 适用场景:简单的异步操作,例如单个文件读取操作,只有一层异步调用时使用较为方便。例如:
const fs = require('fs');
fs.readFile('example.txt', 'utf8', (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data);
});
- Promise
- 特点:Promise是一个代表异步操作最终完成(或失败)及其结果值的对象。它通过链式调用的方式来处理异步操作,避免了回调地狱。Promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败),状态一旦改变就不会再变。
- 适用场景:多个异步操作有顺序依赖关系,或者需要对多个异步操作的结果进行统一处理时。例如:
const fs = require('fs');
const util = require('util');
const readFile = util.promisify(fs.readFile);
readFile('example.txt', 'utf8')
.then(data => {
console.log(data);
return readFile('another.txt', 'utf8');
})
.then(anotherData => {
console.log(anotherData);
})
.catch(err => {
console.error(err);
});
- async/await
- 特点:基于Promise,它是一种更简洁的异步代码书写方式。
async
函数返回一个Promise对象,await
只能在async
函数内部使用,它会暂停async
函数的执行,等待Promise被解决(resolved或rejected),然后恢复async
函数的执行并返回Promise的解决结果。这种方式让异步代码看起来像同步代码,极大地提高了代码的可读性。
- 适用场景:与Promise适用场景类似,但更适合于需要以同步方式书写异步代码的情况,尤其是在处理复杂的异步流程时。例如:
const fs = require('fs');
const util = require('util');
const readFile = util.promisify(fs.readFile);
async function readFiles() {
try {
const data1 = await readFile('example.txt', 'utf8');
console.log(data1);
const data2 = await readFile('another.txt', 'utf8');
console.log(data2);
} catch (err) {
console.error(err);
}
}
readFiles();