zoukankan      html  css  js  c++  java
  • 说一说promise

    一、ES6 promise

    现在ES6很火,今天打算捋一捋ES6中promise,弄清楚核心,掌握这个知识点。

    promise到底是什么?

    通过console.dir(Promise)

    我们可以看到Promise是一个构造函数,有resolve(),reject(),all(),race()等方法,也有catch(),then()等构造方法

    resolve,reject

    解析一个Promise例子:

    例子1:
    var p = new Promise(fucntion(resolve,reject){
        //这里一般有异步操作
        console.log("执行到此");
        resolve("执行成功")
        reject("执行失败"); 
    })

    其实resolve()和reject()大致相当于一个优化过的回调函数,如果函数执行失败(状态为reject),就会执行reject(),如果函数顺利执行(状态为fullfiled),就会执行其实resolve()。

    这里有一点,如果函数里面有其他操作,无论成功与否,都会先执行,所以会先输出“执行到此”。

    为此,一般都是把promise包在函数中,阻止其他操作自动执行。通过在函数中返回这个promise实例,执行函数

    例子2:
    function runPromise(){
        var p = new Promise(fucntion(resolve,reject){
            //这里一般是异步操作
            console.log("执行到此");
            resolve("执行成功")
            reject("执行失败"); 
        }); 
        return p;
    }
    
    runPromise();

    then

    有了例子2,接下去就是ES6的一个精髓,链式操作(对付回调地狱的一种方式)

    例子3:
    runPromise().then(function(){return x;})
        .then(function(){return y;})
        .then(function(){return z;});

    第一个then()方法相当于resolve(),在runPromise()正常执行时调用,第二个then()方法处理第一个then()返回的值,如此类推。

    如果想处理runPromise()失败的调用,

    例子4
    runPromise().then(function(data1){return x;},fucntion(data2){return x;})
        .then(function(){return y;})
        .then(function(){return z;});

    catch

    当然例子4中可以用catch()代替then()的失败调用

    例子5
    runPromise().then(function(){return x;})
        .catchfunction(){return y;});

    当然,这里的catch()还有更多的功能,就是在上述代码出异常(代码错误时),不会卡死报错,会进入catch()方法,与try/catch方法有相同功能。

    all

    如果你想同时输出多个Promise怎么办,用all()方法,可实现并行执行异步操作的能力,并且是在Promise里的所有异步操作执行完才回调

    例子6
    Promise.all([方法1,方法2,方法3]).then(fucntion(){});

    这里会先执行方法1,方法2,方法3的普通方法,然后把他们的resolve()输出成一个数组。

    输出如下:

    方法1普通输出
    方法2普通输出
    方法3普通输出
    [方法1的resolve(),方法2的resolve(),方法3的resolve()]
    

    这种操作可用于预加载各种资源如图片等

    race

    all()方法的效果实际上是「谁跑的慢,以谁为准执行回调」,那么相对的就有另一个方法「谁跑的快,以谁为准执行回调」,这就是race方法,这个词本来就是赛跑的意思。

    例子7
    Promise.race([方法1,方法2,方法3]).then(fucntion(){});

    假设方法1最先输出,则:

    方法1普通输出
    方法1的resolve()
    方法2普通输出
    方法3普通输出
    

    二、JQuery的deferred

    jQuery用$.Deferred()实现了Promise规范(这是一种理念)

    $.Deferred() 创造了一个Deferred对象,一个 Deferred 对象开始于挂起状态,任何使用 deferred.then(), deferred.always(), deferred.done(), 或者 deferred.fail() 添加到这个对象的回调函数都是排队等待执行的。调用 deferred.resolve转换延迟到解决状态后立即执行设置的 doneCallbacks 。调用 deferred.reject() 转换延迟到拒绝状态后立即执行设置的 failCallbacks 。一旦对象已经进入了解决或拒绝状态,它保持该状态。

    done、fail、always

    jquery增加了两个语法糖方法,done和fail,分别用来指定执行完成和执行失败的回调

    var deferred = $.Deferred();
    var promise = deferred.promise();
    /*$.Deferred的特性在外部可以操作deferred的状态,
    所以加上promise方法拒接外部操作状态*/
    
    这里:
    promise.then(function(){
        console.log('执行完成');
    }, function(){
        console.log('执行失败');
    });
    
    相当于:
    promise.done(function(){
        console.log('执行完成');
    })
    .fail(function(){
        console.log('执行失败');
    })
    //.always(function(){
    //    console.log('一定执行');
    //});

    done()相当于添加deferred.reslove()的回调,fail()相当于添加deferred.reject()的回调。但不管成功与否,都会执行 always() 添加的回调。always也是一个语法糖。

    then

    和ES6的Promise对象一样,也支持then方法

    when

    与ES6中的all方法功能一样,并行执行异步操作,在所有的异步操作执行完后才执行回调函数。不过与ES6的all的参数稍有区别,它接受的并不是数组,而是多个Deferred对象。

    $.when(方法1(), 方法2(), 方法3())
    .then(function(data1, data2, data3){
        console.log('全部执行完成');
        console.log(data1, data2, data3);
    });
    

    这里,jquery中没有像ES6中的race方法

    再拓展Deferred对象的使用方法

    把普通操作封装成一个回调函数

    var $def = $.Deferred();
    var wait = fucntion(){
        var tasks = fucntion(){
            alert("执行完毕!");
            $def.resolve(); // 改变deferred对象的执行状态
        }
    
        tasks();
    
        return $def.promise();
    }
    
    $.when(wait())
        .done(function(){ alert("执行成功!"); })
        .fail(function(){ alert("执行出错!"); });

    三、ajax与Deferred的关系

    success、error与complete

    分别表示ajax请求成功、失败、结束的回调。是Ajax的语法糖。

    success对应done,error对应fail,complete对应always,就这样,只是为了与ajax的参数名字上保持一致而已

    例子:
    $.ajax(/*...*/)
        .success(function(){/*...*/})
        .error(function(){/*...*/})
        .complete(function(){/*...*/})
     
  • 相关阅读:
    SlidingMenu官方实例分析8——CustomAnimation
    SlidingMenu官方实例分析7——SlidingContent和SlidingTitleBar区别
    SlidingMenu官方实例分析5——FragmentChangeActivity
    SlidingMenu官方实例分析4——AttachExample
    云虚拟主机和云服务器的区别
    SAP MM常用表
    dedecms 模板文件不存在,无法解析文档"的终极各种解决办法
    js代码如何测试代码运行时间
    java 连接msql数据库
    Java 创建xml文件和操作xml数据
  • 原文地址:https://www.cnblogs.com/ZpandaZ/p/7397090.html
Copyright © 2011-2022 走看看