2.2.JavaScript异步流程控制-Promise的使用

212 阅读1分钟

为什么需要promise

  1. 回调地狱,如果多个异步请求并且有连带关系,需要回调嵌套;
  2. 多个异步实现并发的话,对异步代码无法实现同步的返回结果;
  3. 错误处理不方便;

Promise概念

  1. promise(承诺)就是一个类型;
  2. new Promise时需要传递一个executor执行器(同步执行);
  3. executor中有两个参数:resolve成功、reject失败;
  4. 每个promise的实例上都有一个then方法,其中两个函数(成功函数和失败函数)
  5. promise中有三个状态,同意、成功态:Resolved;失败态:Rejected;等待态:Pending;
    • 默认情况是pending -> resolved;pending -> rejectd;resolved 不能和 rejected 相互转化

Promise解决异步编程

let fs = require('fs');
function read(file) {
  return new Promise(function (resolve, reject) {
    fs.readFile(file, 'utf8', function (err, data) {
      if (err) reject(err);
      resolve(data);
    })
  });
}
// promise的链式调用解决回调嵌套的问题
// then方法执行完会判断返回的结果,如果是promise,会执行这个promise,然后取到它的结果
// promise 每次调用then后 返回一个新的promise
read('name.txt').then(function(data){
  // data === 'age.txt'
  return read(data);
}).then(function(data){
  // data === 'address.txt'
  return read(data);
}).then(function(data){
  // data === '北京'
  console.log(data);
}).then().then().then() // 值的穿透
.catch(function(err){
  // 错误输出
  console.log('catch', err)
})

Promise.all并发执行

  1. 多个异步并发执行,需要同一时刻获取最终的结果
  2. Promise提供了一个并发的方法:Promise.all,实现并发执行promise,all方法返回的结果是一个promise
  3. 运用计数器原理
Promise.all([read('./name.txt'), read('./age.txt')]).then(function (data) {
  console.log(data); // 保证顺序和调用时一样
}).catch(function (err) {
  console.log(err);
});