异步
异步的特点:不等待 非阻塞,同时处理大量的并发请求,使得性能提高
JavaScript为单线程运行,如果程序为同步执行的,在发送http请求,读写文件等操作中,线程阻塞,程序将无法响应其他操作。所以实现异步后,性能有很大提升。且由于是单线程运行,没有线程同步等的问题。
阻塞代码
// 阻塞式的
const fs = require("fs");
const data = fs.readFileSync("./hello.js");
console.log(data.toString());
console.log("123");
// 先输出文件内容,再输出123
JavaScript异步编程的几种常见模式
- 回调函数 callback
- Promise
- Generator
- async / await
- Event
回调函数
回调函数在异步操作完成后被调用
// 非阻塞
const fs = require("fs");
fs.readFile("./hello.js", function (err, data) { // 回调函数
// 错误优先机制
if (err) {
console.log(err.stack);
return;
}
// 未指定编码格式,得到的data为buffer对象,使用toString方法
console.log(data.toString());
});
console.log("123");
// 先输出123,再输出文件内容
Promise
用法
const myReadFile = (filename) => {
return new Promise((resolve, reject) => {
fs.readFile(filename, "utf8", (err, data) => {
if (err) {
reject(err);
}
resolve(data);
});
});
};
myReadFile('./hello.js')
.then(res => {
console.log(res);
}, (error) => {
console.error("error: " + error);
});
使用Promise解决回调地狱
func1()
.then(res1 => {
// do something
return func2();
})
.then(res2 => {
// do something
return func3();
})
.catch(error => {
// handle error
})
使用模块
const fs = require("fs");
const { promisify } = require("util");
// promisify 将 fs.readFile包装成promise对象
const readFile = promisify(fs.readFile);
async function asyncReadFile() {
try {
const data = await readFile("./hello.js");
console.log(data.toString());
} catch (error) {
console.log(error.stack);
}
}
asyncReadFile();
generator
const fs = require("fs");
const { promisify } = require("util");
// // promisify 将 fs.readFile包装成promise对象
const readFile = promisify(fs.readFile);
function* read() {
yield readFile("./hello.js");
}
let ge = read();
ge.next().value.then((data) => {
console.log(data.toString());
});
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!