一、异步编程的核心价值
1.1 单线程事件循环
fs.readFile('file.txt', (err, data) => {
if (err) throw err;
console.log(data);
});
1.2 异步模式演进
二、核心模式详解
2.1 回调函数陷阱
function doWork() {
fs.readFile('file1.txt', (err, data1) => {
if (err) return handleError(err);
fs.readFile('file2.txt', (err, data2) => {
if (err) return handleError(err);
console.log(data1 + data2);
});
});
}
2.2 Promise链式调用
const readAsync = (file) =>
new Promise((resolve, reject) => {
fs.readFile(file, (err, data) =>
err ? reject(err) : resolve(data)
);
});
readAsync('file1.txt')
.then(data1 => readAsync('file2.txt'))
.then(data2 => console.log(data1 + data2))
.catch(err => console.error(err));
2.3 async/await优雅实现
async function processFiles() {
try {
const data1 = await readAsync('file1.txt');
const data2 = await readAsync('file2.txt');
console.log(data1 + data2);
} catch (err) {
console.error(err);
}
}
三、模式对比实战
3.1 核心特性对比
维度 | 回调函数 | Promise | async/await |
---|
可读性 | 低(嵌套层级高) | 中(链式调用) | 高(同步风格) |
错误处理 | 难(层层传递) | 改善(统一catch) | 优秀(try/catch) |
性能开销 | 基础 | 略高(链式创建) | 最高(函数封装) |
兼容性 | 全版本支持 | ES6+ | ES7+ |
3.2 性能测试数据
四、框架选型实战
4.1 选择回调的场景
const http = require('http');
http.createServer((req, res) => {
fs.createReadStream('largefile.txt')
.pipe(res);
}).listen(3000);
4.2 Promise的中间场景
const promiseDB = (sql) =>
new Promise((resolve, reject) => {
oldDB.query(sql, (err, results) =>
err ? reject(err) : resolve(results)
);
});
4.3 async/await的现代方案
async function handleRequest(req, res) {
try {
const user = await db.getUser(req.session.userId);
const orders = await db.getOrders(user.id);
res.send({ user, orders });
} catch (err) {
res.status(500).send('Error');
}
}
五、性能优化技巧
5.1 并发控制优化
const urls = ['api1', 'api2', 'api3'];
Promise.all(urls.map(url => fetch(url)))
.then(responses => Promise.all(responses.map(r => r.json())))
.then(data => console.log(data));
5.2 错误边界设计
async function safeFunc() {
try {
await riskyOperation();
} catch (err) {
sentry.captureException(err);
throw err;
}
}
六、常见问题解决方案
6.1 回调地狱解救方案
function readFile1() {
return new Promise((resolve, reject) => {
fs.readFile('file1.txt', (err, data) =>
err ? reject(err) : resolve(data)
);
});
}
function readFile2() {
return new Promise((resolve, reject) => {
fs.readFile('file2.txt', (err, data) =>
err ? reject(err) : resolve(data)
);
});
}
6.2 Promise死锁问题
new Promise((resolve, reject) => {
setTimeout(() => resolve('data'), 1000);
}).then(data => {
console.log(data);
});
七、总结与选型建议
7.1 选型决策树
7.2 最佳实践
npm install @types/node --save-dev
npm run build -- --target ES2017