ES6 Promise的理解应用

本文是读了阮一峰大神《ES6标准入门》-Promise 对象 后的一些个人的小总结

1. 什么是promise?

1.1 重要概念

一个 Promise 必然处于以下几种状态之一:

  • 待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled): 操作成功完成。
  • 已拒绝(rejected): 操作失败。

待定状态的 Promise 对象要么会通过一个值被兑现(fulfilled),要么会通过一个原因(错误)被拒绝(rejected)。

1.2 创建promise

  • promise对象是一个构造函数,用来生成promise实例
  • 该构造函数会把一个叫做“处理器函数”(executor function)的函数作为它的参数。这个“处理器函数”接受两个函数resolve 和 reject 作为其参数。
  • 当异步任务顺利完成且返回结果值时,会调用 resolve 函数;而当异步任务失败且返回失败原因(通常是一个错误对象)时,会调用reject 函数。
    • resolve:pending ——> resolved, 异步操作的结果作为返回值
    • reject:pending ——> rejected, 错误原因作为返回值
  • promise实例生成以后,用 then 方法指定resolved状态和rejected状态的回调函数

注:为了方便,resolved(表示 promise 已经处于已敲定(settled)状态)指fulfilled状态。

const promise = new Promise(function(resolve,reject){
    
    
  // some codes
  if(/*异步操作成功*/){
    
    
    resolve(value);
  }else{
    
    
    reject(error);
  }
});
//then方法接受两个回调函数作为参数,第二个函数不一定提供
promise.then(function(value){
    
    
  //suc
},function(error){
    
    
  //fail
});

举一个栗子:

function timeout(ms) {
    
    
  return new Promise((resolve, reject) => {
    
    
    setTimeout(resolve, ms, 'done'); //done是resolve函数的参数,这里就是value
  });
}

timeout(3000).then((value) => {
    
    
  console.log(value);
});

上面栗子是说,过了指定时间(本例3000ms)后promise实例的状态变成resolved,触发then方法的回调函数打印出结果(done)

2. promise的执行顺序

  • promise新建后立即执行
  • then方法指定的回调函数,在当前脚本所有同步任务执行完成后才执行

直接来看栗子叭~~

console.log('Hi!');
let promise = new Promise(function(resolve, reject) {
    
    
  console.log('I am Promise'); //新建后立即执行
  resolve();
});
console.log("I'm tom");
promise.then(function() {
    
    
  console.log('resolved.'); //在当前脚本所有同步任务执行完成后才执行
});
console.log("I'm a boy");

结果如下:
在这里插入图片描述

3. 使用promise可以避免回调地狱

初次学习promise的时候,老师说promise可以避免回调地狱。脑子里面一直似懂非懂的,这下终于弄懂了来记录一下。
再举个栗子~~
我们现在想模拟一下接力跑的过程,我们如何用代码实现呢?

function f1(next){
    
    
  console.log("f1起跑...");
  setTimeout(()=>{
    
    
    console.log("f1到达,传递接力棒");
    next();
  },4000)
}
function f2(next){
    
    
  console.log("f2起跑...");
  setTimeout(()=>{
    
    
    console.log("f2到达,传递接力棒");
    next();
  },5000)
}
function f3(next){
    
    
  console.log("f3起跑...");
  setTimeout(()=>{
    
    
    console.log("f3到达终点");
    next();
  },3000)
}
f1(function(){
    
    
  f2(function(){
    
    
    f3(function(){
    
    
        console.log("比赛结束!");
    })
  })
})

通过上面代码,我们的确得到了预期的结果:
在这里插入图片描述
我们难以想象如果有更多的层层嵌套的回调函数,我们还能这样的轻松的、不出错的写出代码吗?
这样的代码可读性低、编写费劲、容易出错,我们该如何解决呢?
来看看用promise如何解决:

function f1(next){
    
    
  return new Promise(function(resolve,reject){
    
    
    console.log("f1起跑...");
    setTimeout(()=>{
    
    
      console.log("f1到达,传递接力棒");
      resolve();
    },4000)
  }) 
}
function f2(next){
    
    
  return new Promise(function(resolve,reject){
    
    
    console.log("f2起跑...");
    setTimeout(()=>{
    
    
      console.log("f2到达,传递接力棒");
      resolve();
    },5000)
  }) 
}
function f3(next){
    
    
  return new Promise(function(resolve,reject){
    
    
    console.log("f3起跑...");
    setTimeout(()=>{
    
    
      console.log("f3到达终点");
      resolve();
    },3000)
  }) 
}
f1()
.then(f2)
.then(f3)
.then(()=>console.log("比赛结束!"));

总结:

  • 使用then方法依次指定多个回调函数
  • 第一个回调函数完成后,会将结果作为参数传入第二个回调函数
  • 采用链式的then,可以指定一组按照次序调用的回调函数。若第一个回调函数返回一个promise对象,这时后面的回调函数会等待该promise对象状态发生变化,才会被调用

还有一些promise的静态方法没有总结,下次补上~

猜你喜欢

转载自blog.csdn.net/weixin_44410783/article/details/111869575
今日推荐