异步的发展历程:
callback->promise(ES6)->async/await(ES7)
为什么使用异步?
同步性能低,而且会阻塞主线程,所以用异步。
异步的缺点有哪些?
-
- 异步方法如果出错了,try/catch不能捕获其中的错误。
-
- 异步方法获取的结果,不能通过return直接返回。
-
- 回调函数多次嵌套的写法不优雅,不易捕获异常,调试困难(即所谓的回调地狱)。
传统的callback方式存在如下问题:
- 问题1:两个异步请求 第二个请求依赖于第一个请求的返回结果(多层嵌套).
- 问题2: 两个异步请求 同时拿到两个异步请求的结果 [result1,result2]. (问题2的解决方案:after,发布订阅模式)
ES6中的Promise可以轻松解决传统callback中的上述两个问题。
//1) 读取两个文件,第一个文件里内容是第二个文件的路径,要求输出第二个文件的内容。
let fs = require('fs');
function read(path, encoding) {
return new Promise((resolve, reject) => {
fs.readFile(path, encoding, function (err, data) {
if (err) return reject(err);
resolve(data);
});
})
}
read('./1.txt', 'utf8').then(data => {
return read(data, 'utf8');//执行结果传递给下一次then
},err=>{
console.log(err);
}).then(data => {
return [data];
}).catch(err=>{
console.log(err);
});
成功的回调 or 失败的回调执行后可以返回一个promise, 会将这个promise的执行结果传递给下一次then.
// 2) Promise.all()可以解决多个异步请求问题
// 等待两个promise都执行完成后
// all方法会返回一个新的promise
// 如果有一个失败就失败了
Promise.all([read('1.txt', 'utf8'), read('2.txt', 'utf8')]).then(data=>{
console.log(data);
},err=>{
console.log(err);
});
创建一个一出生就成功或者失败的promise:
Promise.resolve('123').then(data=>{
console.log(data);
})
Promise.reject('123').then(null,err=>console.log(err))