面试题答案
一键面试使用Promise优化性能并避免回调地狱
- Promise基础示例
假设我们有一个简单的异步函数模拟文件读取,使用
fs
模块的readFile
方法,其原始回调形式如下:
const fs = require('fs');
fs.readFile('example.txt', 'utf8', (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data);
});
使用Promise封装后:
const fs = require('fs');
const util = require('util');
const readFilePromise = util.promisify(fs.readFile);
readFilePromise('example.txt', 'utf8')
.then(data => {
console.log(data);
})
.catch(err => {
console.error(err);
});
- 多个异步操作优化 假设有多个数据库查询(这里简单模拟为异步函数)和文件读取操作。
// 模拟数据库查询
function dbQuery1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Result of dbQuery1');
}, 1000);
});
}
function dbQuery2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Result of dbQuery2');
}, 1500);
});
}
// 模拟文件读取
const fs = require('fs');
const util = require('util');
const readFilePromise = util.promisify(fs.readFile);
// 多个异步操作串行执行
dbQuery1()
.then(result1 => {
console.log(result1);
return dbQuery2();
})
.then(result2 => {
console.log(result2);
return readFilePromise('example.txt', 'utf8');
})
.then(data => {
console.log(data);
})
.catch(err => {
console.error(err);
});
// 多个异步操作并行执行
Promise.all([dbQuery1(), dbQuery2()])
.then(results => {
console.log(results[0]);
console.log(results[1]);
return readFilePromise('example.txt', 'utf8');
})
.then(data => {
console.log(data);
})
.catch(err => {
console.error(err);
});
使用async/await优化性能并避免回调地狱
- async/await基础示例
const fs = require('fs');
const util = require('util');
const readFilePromise = util.promisify(fs.readFile);
async function readFileAsync() {
try {
const data = await readFilePromise('example.txt', 'utf8');
console.log(data);
} catch (err) {
console.error(err);
}
}
readFileAsync();
- 多个异步操作优化
// 模拟数据库查询
function dbQuery1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Result of dbQuery1');
}, 1000);
});
}
function dbQuery2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Result of dbQuery2');
}, 1500);
});
}
// 模拟文件读取
const fs = require('fs');
const util = require('util');
const readFilePromise = util.promisify(fs.readFile);
async function performOperations() {
try {
// 串行执行
const result1 = await dbQuery1();
console.log(result1);
const result2 = await dbQuery2();
console.log(result2);
const data = await readFilePromise('example.txt', 'utf8');
console.log(data);
// 并行执行
const [result3, result4] = await Promise.all([dbQuery1(), dbQuery2()]);
console.log(result3);
console.log(result4);
const data2 = await readFilePromise('example.txt', 'utf8');
console.log(data2);
} catch (err) {
console.error(err);
}
}
performOperations();
处理异步操作中的错误
- Promise方式:在Promise链中,每个
.then
方法后面都可以接一个.catch
方法来捕获该链中前面Promise产生的错误。如果没有.catch
,错误会一直向上冒泡到全局未捕获拒绝处理程序。 - async/await方式:在
async
函数中,使用try...catch
块来捕获await
操作产生的错误。如果没有try...catch
,错误会抛出到函数外部,需要在调用该async
函数的地方捕获处理。