Promise入门之基本用法

Promise入门之基本用法

背景

在咱们使用异步函数好比ajax进行编写代码,若是咱们须要不少个ajax请求不一样的接口,而下一个接口须要依赖上一个接口的返回值,这样,咱们的代码则须要在各类回调函数中嵌套,这样一层一层地下去,就造成了回调地狱。
可是promise的出现则不须要嵌套就能解决这个问题。什么是promise?promise本质实际上是一个对象,用于传递异步操做的信息。而且promise这个对象提供了相对应的API,知足咱们的需求开发。ajax

建立promise对象

let pro = new Promise(function(resolve, reject){
    // 异步处理逻辑
    // 处理完毕以后调用resolve或者reject
})

promise对象跟其余普通对象的建立方法同样,只须要new一个新的对象便可,接受一个函数做为参数,而且该函数中的参数分别为两个回调函数,用于进行不一样的逻辑处理。
在定完一个promise对象以后,咱们能够经过调用then方法来执行其对应的逻辑数组

pro.then(function(res){
    // 若是promise对象调用了resolve方法,则进入该函数逻辑
}, function(err){
    // 若是promise对象调用了reject方法,则进入该函数逻辑
})

promise的状态

promise的实例主要有如下三种状态:
①pending: 处理中
②fulfilled: 成功
③rejected: 失败promise

pending状态的promise能够转化为fulfilled状态或者rejected状态,该转化不可逆且只能转化一次。同时,fulfilled状态和rejected状态只能由pending状态转化,相互不能转化。如图异步

clipboard.png

pending状态下的promise在处理完业务逻辑,且能正常退出时即可以执行resolve方法,从而进入fulfilled状态;
若pending状态下的promise在处理业务逻辑的过程当中出现异常错误,或者主动调用reject方法,则进入rejected状态。async

let pro = new Promise(function(resolve, reject){
    if(// 逻辑处理完毕且能正常退出){
        resolve()
    }
    else{
        // 异常错误抛出
        reject()
    }
})

pro.then(function(res){
    // 若是promise对象调用了resolve方法,则进入该函数逻辑
}, function(err){
    // 若是promise对象调用了reject方法,则进入该函数逻辑
})

链式调用

由于promise对象中的then方法的返回值是一个新的promise对象,所以能够实现链式调用。但后一个then方法的执行必须等待前一个then方法返回的promise对象状态转为fulfilled或者rejected,若promise对象处于pending状态下,则后一个then方法只能等待。函数

pro.then(function(res){
    // 第一个promise对象逻辑执行
    return newPro;// 返回一个新promise
}).then(function(res){
    // 对newPro这个对象进行处理
})
// ...能够一直链式调用下去

异常捕捉

promise中的catch方法其实就是pro.then(null, rejection),用户捕捉代码运行中的错误异常。优化

pro.then(function(res){
    // 逻辑处理,但存在异常
}).catch(function(err){
    // 捕捉上一个then函数中所出现的异常错误
})

此外,catch方法的所捕捉的异常不只仅局限于上一个then方法内,而是能够把错误一直传递下来,直至遇到的第一个catch,而后被捕捉。如链式调用中:spa

pro.then(function(res){
    // 逻辑处理,但存在异常
}).then({
    // 逻辑处理
}).catch(function(err){
    // 捕捉上面第一个出现异常的then函数中所出现的错误
})

promise.all

promise.all方法能够接受一个由promise组成的数组做为参数,包装成一个新的promise对象,而且按照数组中promise的顺序进行异步执行。如:code

let pro1 = new Promise(function(resolve, reject){});
let pro2 = new Promise(function(resolve, reject){});
let pro3 = new Promise(function(resolve, reject){});

let proAll = promise.all([pro1, pro2, pro3]);

proAll的状态由pro1,pro2,pro3三者共同决定:
①pending: 处理中,pro1,pro2,pro3中无rejected且存在pending状态。
②rejected: pro1,pro2,pro3中存在一个rejected。
③fulfilled:pro1,pro2,pro3三者均为fulfilled。对象

当proAll的状态为fulfilled时,会返回一个数组,该数组中的元素则是上面由promise组成的数组相对应执行后的结果。

promise.race

promise.race所接受的参数与promise.all一致,但promise.race的返回值则是由pro1,pro2,pro3三者中最早完成的promise对象决定,而且返回值为该最先完成的promise对象的返回值。

let proAll = promise.race([pro1, pro2, pro3]);

promise.resolve

promise.resolve方法能将一个对象转换成promise对象

let newPro = promise.resolve(obj);

①若obj不具备then方法,则newPro直接变为fulfilled状态

let newPro = promise.resolve('i am not a promise');

newPro.then(function(str){
    console.log(str) // 输出 i am not a promise
})

②若是obj本就是一个Promise对象,则promise.resolve会将obj直接返回。

promise.reject

promise.reject方法与promise.resolve同样,能将一个对象转换成promise对象,但返回的promise对象的状态为rejected。

async/await

async是关键词,在一个函数名以前加上该关键词,代表该函数内部有异步操做,而这异步操做应该返回一个promise对象,而且在这异步操做以前添加await关键词。当函数执行的时候,遇到await则会先进行Promise的逻辑处理,带promise的状态再也不为pending时再执行该函数后面的语句。

let pro = new Promise(function(resolve, reject){
    // 异步处理逻辑
    resolve();
})

async function asyncFunc(){
    // 正常执行的语句
    await pro;
    // 等待promise处理完以后再执行的语句
}

asyncFunc();

总结

promise的出现,为咱们编写异步函数定下很多规则,在优化咱们代码的同时也能减小代码量,并加强可读性,但也需严格遵照promise/A+的规范进行promise的开发。

相关文章
相关标签/搜索