阅读 936

细说Promise之常用方法

Promise是什么?

Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件更合理且更强大。它最早由社区提出并实现,ES6将其写进了语言标准,统一了用法,并原生提供了Promise对象。

Promise与回调恶魔

在我们开发业务中经常会遇见回调函数需顺序执行,都是怎么处理的呢,代码层层嵌套?ajax、callback、Promise、generator、async、await。。。想必大家都很熟悉,下边就通过小栗子来着重研究下Promise

需求:三个小球从初始位置依次滚动到结束位置

function move(ele,target,callback){
        //小球滚动的逻辑
    } 
    //回调函数处理
    move(ball1,400,function(){
        move(ball2,400,function(){
            move(ball3,400,function(){
                alert('滚动结束')
            })
        })
    }) 
    //这样看,代码层级还算看的清,如果有更多的小球呢,代码的嵌套就更多了,就看到金字塔了
复制代码

来看看用Promise怎么实现

move(ball1,400).then(function(){
    return move(ball2,400);
}).then(function(){
    return move(ball3,400);
}).then(function(){
    alert('滚动结束')
})
//代码少了层级嵌套
复制代码

上边只是举个简单的例子,初步理解Promise的简单使用。如果我们回调里要处理的业务逻辑更复杂,Promise就更能大显神功!

Promise基础

1.1、Promise的基础

var p = new Promise((resolve,reject)=>{
    //some code
    if(/*异步操作成功*/){
        resolve(value);
    }else{
        reject(error);
    }
})
//Promise实例生成以后,可以用then方法分别制定Resolved状态和Rejected状态的回调函数
p.then((value)=>{
    //success
},error=>{
    //failed
})
复制代码

1.2、Promise状态

Promise有三种状态:pending(进行中)、fulfilled(成功)、rejected(失败)

一旦状态改变,就不会再变,状态的改变只有两种可能:

1)从pending变为fulfilled
2)从pending变为rejected

警告⚠️,状态不可逆,不可能会从fulfilled变为rejected或从rejected变为fulfilled

可参考Promise A+规范:

Promise.then()

let p = new Promise((resolve,reject)=>{
    resolve();
})
p.then((value)=>{
    //success
},error=>{
    //fail
})
复制代码

then方法的链式调用:会取promise的返回结果作为外层下一次then的参数;如果返回的是普通值,直接把值作为外层下一次then的参数;then方法调用后,返回的是一个新的Promise实例

let p = new Promise((resolve,reject)=>{
    resolve();
})
p.then((data) => {
    return new Promise((resolve,reject)=>{
        resolve(new Promise((resolve,reject)=>{
            resolve(success);
        }));
    })
}, err => {
    console.log('p:err', err);
}).then((data)=> {
    console.log(data); //100
})
复制代码

Promise新建后会立马执行,then方法的回调等都执行完后再执行

let p = new Promise((resolve,reject)=>{
    console.log(1);
    resolve();
})
p.then(()=>{
    console.log(2);
})
console.log(3);
//执行结果 1  3  2
复制代码

Promise.resolve()与Promise.reject()

Promise.resolve()方法在回调时被调用直接返回一个Resolved状态的Promise对象。

let p = Promise.resolve('Hello');
p.then(function (a){
  console.log(a); // Hello
});
复制代码

Reject的作用就是把Promise的状态置为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调。

let p = new Promise((resolve,reject)=>{
    throw new Error('抛出错误')
});
p.then(null, function (err){
  console.log(err); //抛出错误
});
复制代码

Promise.all()

将多个Promise实例包装成一个新的Promise实例。p的状态由p1,p2,p3决定,1)只有p1,p2,p3的状态都变为Fulfilled,p的状态才会变成Fulfilled 2)只要p1,p2,p3中有一个被Rejected,p的状态就变成Rejected,此时第一个被Rejected的实例的返回值传递给p的回调函数

let p1 = Promise.resolve(1);
let p2 = Promise.resolve(2);
let p3 = Promise.resolve(3);
Promise.all([p1,p2,p3]).then(data=>{
    console.log(data); // [ 1, 2, 3 ]
})
复制代码

Promise.race()

与Promise.all()用法类似,但是状态的改变却不同,只要p1,p2,p3中有一个实例先改变状态,p的状态就跟着改变

let p1 = Promise.resolve(1);
let p2 = Promise.resolve(2);
let p3 = Promise.resolve(3);
Promise.race([p1, p2, p3]).then(data=> {
    console.log(data);  // 1
});
复制代码

Promise.catch()

let p = new Promise((resolve,reject)=>{
    throw new Error('抛出错误')
});
p.catch(error=>{ //捕获错误
    console.log(error);
})
复制代码
//catch相当于一个then方法没有成功回调
let p = new Promise((resolve,reject)=>{
    reject();
})
p.then(()=>{

}).catch(e=>{
    console.log(e); //捕获then方法中的错误
})
复制代码

总结:以上为Promise常用的方法,希望对大家有所帮助,也记录下自己阶段性的理解,以后会追加Promise实现原理,敬请期待!

文章分类
前端