promise

  在es5中,处理异步采用的是回调机制,比如定时器、DOM事件处理程序、ajax异步请求等;但是回调机制容易造成"回调地狱",以及当逻辑多时代码不易维护;比如:

// 定时器
setTimeout(function(){

    // DOM事件处理程序
    document.addEventListener('click',function(){

        // ajax异步请求
        Ajax('http://...',function(res){
            
        });

    });

},1000)

  很容易看出,回调机制问题所在:

    1.代码横向书写,形成金字塔形式;造成“回调地狱”

     2.如果每个异步中有很多业务需要处理,就会造成代码不易维护

  因此,在ES6中引入了Promise机制来解决异步问题;( jQuery早在1.5版本时就实现了类似的机制 ); 关于异步处理机制,大致上分成三个阶段:

    1.回调机制 

    2.promise (ES6)

    3.async / await (ES7中会实现)

异步处理机制Promise

  Promise 是个构造函数,需要通过new 出一个对象;先看看Promise这个函数对象上的方法:

// 原型上的方法
Promise.prototype.catch()
Promise.prototype.then()

// Promise函数对象上的方法
Promise.resolve()
Promise.reject()
Promise.all()
Promise.race()

  Promise机制一般使用步骤如下:

var pro = new Promise(function(resolve,reject){
    if(...){
         resolve(res); // 成功时执行 panding->fulfiled
    }else{
        reject(err); // 失败时执行 panding->rejected
    }
})

pro.then(
    function(res){}, // 对应 resolve
    function(err){} // 对应 reject
)

  明确几点:

    1. Promise构造函数参数是个函数,这个函数的参数是resolve,reject;成功时,调用resolve,对应执行then()中的函数;反之,调用reject,执行then()中的第二个函数;

    2. Promise对象存在三种状态:pending(初始状态),fulfiled(成功并完成),rejected(失败并完成);执行resolve时,pending->fulfiled;执行reject时,pending->rejected;

    3. then函数执行后,返回的仍然是Promise对象,因此可以实现"链式"书写,使得代码由 横向--->纵向;

  现在举个例子,改写回调地狱:

// 定时器,回调地狱
// 不难看出,如果每个回调中的逻辑很多,代码将变得不易维护
setTimeout(function(){
    console.log(1)

    setTimeout(function(){
        console.log(2)

        setTimeout(function(){
            console.log(3)
        },3000)

    },2000)

},1000)

// 使用Promise改写
var pro = function(ms){
    return new Promise(function(resolve,reject){
        setTimeout(resolve,ms)
    })
};

pro(1000)
.then(function(){
    console.log(1)
    return pro(2000);
})
.then(function(){
    console.log(2)
    return pro(3000);
})
.then(function(){
    console.log(3)
})
// 采用Promise方式,就变得非常舒服
// 纵向书写,顺序执行,基本符合人脑的思维方式:同步阻塞
// 避免了回调地狱,同时代码很容易维护

  Promise.prototype.catch()

    Promise函数对象有两个核心函数:then() ,catch() ;then()上文中已经阐述过,现在来看catch();

    catch()是捕获错误的,当异步不管报什么错,都会被catch()捕获;不管在哪个then()后面,一旦报错,进入catch(),将停止执行;

    同时,catch()返回的仍是Promise对象;

var pro = new Promise(function(resolve,reject){
    if(...){
         resolve(res); // 成功时执行 panding->fulfiled
    }
})

pro.then(
    function(res){
        console.log(ss)// ss 没有定义,将会报错
    }, // 对应 resolve
)
.catch(function(err){
    
})

  如果在then()中报错,catch则会捕获这个错误;

  Promise.all() && Promise.race()

    这两个函数在Promise函数对象上,用于执行多个Promise对象;这两个函数的参数都是多个Promise对象,区别如下:

    1.all()函数中,只有所有的Promise对象pending-->fulfiled时,才会执行then()中的resolve,参数为数组,对应all()中的Promise对象数组

    2.race “竞争”;第一个pending-->fulfiled的Promise对象,率先执行then()中的resolve,参数为第一个执行的返回参数;

  感悟:如果熟悉jQuery的延迟对象,ES6中的Promise机制不难理解、掌握;

原文地址:https://www.cnblogs.com/RocketV2/p/8608161.html