Promise:承诺者模式,ES6新增的一个内置类(基础1)

288 阅读3分钟

Promise

  • IE浏览器不兼容排除(EDGE):基于babel-polyfill处理兼容性(原理:自己基于Promise-->Promise A+规范 promisesaplus.com/)
  • Promise是用来管理异步编程的代码,他是一种设计模式(承诺者模式),主要解决异步编程的回调地狱问题

没有promise之前是怎么请求的呢?

项目中,我们的AJAX请求都是'异步'请求的AJAX请求的并行和串行

  • 串行 : 多个AJAX请求,请求之前存在于某种依赖,所以需要等上一个请求完成,才能发送下一个请求,我们把这种方式叫做串行
  •  回调地狱 : 回调函数中嵌套回调函数(套娃操作)
$.ajax({
    url:'xxx1.json',
    method:'GET',
    dataType:'JSON',
    success(value){
      console.log('请求成功',value);
      $.ajax({
        url:'xxx2.json',
        method:'GET',
        dataType:'JSON',
        success(value){
          console.log('请求成功',value);
          $.ajax({
            url:'xxx3.json',
            method:'GET',
            dataType:'JSON',
            success(value){
              console.log('请求成功',value);
            }
          })
        }
      })
    }
  })
  • 并行:可以同时发送多个AJAX请求,请求和请求之间没有依赖(一般需要并发管控)
$.ajax({
        url'xxx1.json',
        success(value) {
            console.log('第一个请求成功:', value);
        }
    });
    $.ajax({
        url'xxx2.json',
        success(value) {
            console.log('第二个请求成功:', value);
        }
    });
    $.ajax({
        url'xxx3.json',
        success(value) {
            console.log('第三个请求成功:', value);
        }
    }); 

初窥Promise

const query1 = () =>{
  return new Promise(resolve=>
    $.ajax({
      url:'./data1.json',
      success(value){
        resolve(value);
      }
    })
    )
}
const query2 = () =>{
  return new Promise(resolve=>
    $.ajax({
      url:'./data2.json',
      success(value){
        resolve(value);
      }
    })
    )
}
const query3 = () =>{
  return new Promise(resolve=>
    $.ajax({
      url:'./data3.json',
      success(value){
        resolve(value);
      }
    })
    )
}

基于promise解决回调地狱

query1()
.then(value=>{
  console.log('第一个请求成功',value);
  return query2();
})
.then(value=>{
  console.log('第二个请求成功',value);
  return query3();
})
.then(value=>{
  console.log('第三个请求成功',value);
}) 
// ||async/await
(async function(){
  let value = await query1();
  console.log('第一个请求成功',value);

  value = await query2();
  console.log('第二个请求成功',value);

  value = await query3();
  console.log('第三个请求成功',value);
})();

new Promise([executior]);

  • 必须传递一个函数,不传递函数则报错,executior执行者
  • executior函数中会有两个形参:reslove & reject (reslove和reject的值都是函数)
  • new Promise的时候,会把传递进来的executior函数立即执行
  • 函数中一般用来管理一个异步编程代码
let p1 = new Promise(function executior(reslove,reject){
//我们管理异步编程的代码,只需要在AJAX请求成功或者失败的时候,把实例p1的状态跟着进行修改,把从服务器获取的结果或者请求失败的原因,作为实例的值即可 / 而成功干啥事情,或者失败做啥事情,全部交给THEN中的onfulfilled/onrejected来进行处理即可
  $.ajax({
      url:'./data1.json',
      success: function(value) {
        //请求成功
        resolve(value)
      },
      error: function(value) {
        //请求失败
        reject(reason)
      },
    })
  });
  p1.then(
   function onfulfilled(value){
     console.log('成功',value);
   },
   function onrejected(reason){
    console.log('失败',reason);
   }
 )

THEN链机制

  • 每执行一次then方法,都会返回一个全新的Promise实例 创建promise实例的方法
  • new Promise([executior])
  • 实例的状态和值由executior函数执行是否报错&resolve/reject函数执行来决定
  • .then(onfulfilled,onrejected),实例的状态和值和onfulfilled或者onrejected的方法执行有关系(不论那个方法执行,都是按照一下规则来影响新返回实例的状态和值)@1、看方法执行是否会报错,如果报错了,则新实例的状态是rejected,值是报错原因 @2、如果没有报错,则再看方法执行的返回值,是否为一个新的promise实例(@NEW),如果是,则@NEW的状态和值,直接决定了,THEN返回的实例的状态和值@3、如果方法返回值不是新的实例,则状态fulfilled,值是函数的返回值
  • Promise.resolve([value]):直接创建一个状态是成功,值是value的实例
  • Promise.reject([reason]):直接创建一个状态是失败,值是reason的实例
  • Promise.all([promise,promise,...]):监听传递进来的数组中,每一个promise实例的状态,当所有实例状态是成功的时候,整体返回实例的状态也是成功,值是一个数组,包含所有实例的结果:如果其中有一个实例是失败的,整体返回的实例就是失败的,值是失败的是那个promise的值
  • Promse.race:就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
//打印什么?请求成功 100 请求失败 0 请求成功 NO
let p1 = new Promise((resolve, reject) => {
  resolve(100);
});
let p2 = p1.then(value => {
  console.log('请求成功:', value);
  return new Promise((_, reject) => {
      reject(0);
  });
}, reason => {
  console.log('请求失败:', reason);
  return new Promise((resolve) => {
      resolve(100);
  });
});
let p3 = p2.then(value => {
  console.log('请求成功:', value);
  return 'OK';
}, reason => {
  console.log('请求失败:', reason);
  return 'NO';
});
p3.then(value => {
  console.log('请求成功:', value);
}, reason => {
  console.log('请求失败:', reason);
});

THEN的"穿透/顺延"机制

  • 如果onfulfilled或者onrejected没有传递,则Promise内部会自动补全
//成功态顺延 请求成功 100
new Promise(resolve =>{
  resolve(100);
}).then(null/*相当于 value=>{return,value} */,reason=>{
  console.log('请求失败',reason);
}).then(value=>{
  console.log('请求成功',value)
})

//失败态顺延 请求失败 100
new Promise((_,reject)=>{
  reject(0)
}/* reason =>{throw reason} */).then(value=>{
  console.log('请求成功',value);
}/* reason =>{throw reason} */).then(value=>{
  console.log('请求成功',value);
}).then(null,reason=>{
  console.log('请求失败',reason);
})

Promise.prototype.cath:主要是处理状态是失败的情况(加在末尾)

  • .then(null,失败态)等价于.catch(失败态)
new Promise((_,reject)=>{
  reject(0)
}/* reason =>{throw reason} */).then(value=>{
  console.log('请求成功',value);
}/* reason =>{throw reason} */).then(value=>{
  console.log('请求成功',value);
}).catch(reason=>{
  console.log('请求失败',reason);
})

Promise.all

Promse.race