zoukankan      html  css  js  c++  java
  • 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机制不难理解、掌握;

  • 相关阅读:
    atexit函数的使用【学习笔记】
    Bootloader与Kernel间参数传递机制 taglist【转】
    Uboot中start.S源码的指令级的详尽解析【转】
    修改u-boot的开机logo及显示过程【转】
    Android 5.x SEAndroid/SElinux内核节点的读写权限【学习笔记】
    【转】IOS 计时器 NSTimer
    【转】iOS-延迟操作方法总结
    ios第三方开源库
    【转】 UIALertView的基本用法与UIAlertViewDelegate对对话框的事件处理方法
    【转】iOS类似Android上toast效果
  • 原文地址:https://www.cnblogs.com/RocketV2/p/8608161.html
Copyright © 2011-2022 走看看