zoukankan      html  css  js  c++  java
  • promise

    有个东西叫回调地狱,promise就是来解决这个的.

    看过的一些相关的技术文章

    Promise介绍

    then和catch方法

    all和race方法

    一些用法的例子


    看过的一些相关的技术文章

    http://liubin.github.io/promises-book/

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise


    Promise介绍

    Promise介绍

    以前写一些异步的东西,都使用回调函数来执行的,这样的写法让人看起来很不舒服

    比如写一个隔几秒就执行的一个回调的东西,然后在回调的时候,开始下一个异步

        setTimeout(function(){
            console.log(11111)
            setTimeout(function(){
                console.log(22222)
                    setTimeout(function(){
                        console.log(33333)
                        setTimeout(function(){
                            console.log(44444)
                                setTimeout(function(){
                                    console.log(55555)
                                },5000)
                        },4000)                    
                    },3000)
            },2000)
        },1000)

    这代码开起来维护起来都会很麻烦的,后来的后来,es6支持原生的Promise,jquery支持Deferred,Promise后,异步问题就容易多了

    一个原生的Promise实现上面的代码

    function setTime(t){
        return new Promise(function(resolve,reject){
            setTimeout(function(){
                resolve();
            },t)   
        });
    }
    setTime(1000)
        .then(function(){
            console.log(11111)
            return setTime(1000);
        })
        .then(function(){
            console.log(22222)
            return setTime(2000);
        })
        .then(function(){
            console.log(33333)
            return setTime(3000);
        })
        .then(function(){
            console.log(44444)
            return setTime(4000);
        })
        .then(function(){
            console.log(55555)
        })      

    什么是Promise?

    Promise是抽象异步处理对象以及对其进行各种操作的组件。 其详细内容在接下来我们还会进行介绍,Promise并不是从JavaScript中发祥的概念。

    Promise最初被提出是在 E语言中, 它是基于并列/并行处理设计的一种编程语言。

    Promise的基本用法

    new Promise(function(resolve, reject) { ... })

    参数

    带有 resolve 、reject两个参数的函数对象。 第一个参数用在处理执行成功的场景,第二个参数则用在处理执行失败的场景。 一旦我们的操作完成即可调用这些函数。

    resolve是实例化后Promise用then里面调用的函数

    reject是实例化后Promise用catch里面调用的函数

    实例化的Promise有3个状态 :等待(pending)、已完成(fulfilled)、已拒绝(rejected)

    实例化的Promise的状态,只可能从“等待”转到“完成”态或者“拒绝”态,不能逆向转换,同时“完成”态和“拒绝”态不能相互转换

    then和catch方法

    then方法

    then方法负责添加针对已完成的处理函数,同一个实例化后的Promise可以有多个then,then方法默认会返回当前的Promise,也可以自己重新实例化一个新的Promise

    then方法对应实例化时候,function的resolve

    catch方法

    catch方法负责添加针对拒绝状态下处理函数,同一个实例化后的Promise可以有多个catch,catch方法默认会返回当前的Promise,也可以自己重新实例化一个新的Promise

    catch方法对应实例化时候,function的resolve

    一个例子

    new Promise(function(resolve,rejected){
        var img = new Image();
        img.src="http://www.paipai.com/xx.jpg";   //这个会失败
        //img.src="https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png" //这个会成功
        img.onload = function(){
            resolve();
        }
        img.onerror = function(){
            rejected();
        }
    })
    .then(function(){
        console.log("图片加载成功!")
    })
    .catch(function(){
        console.log("图片加载失败!")
    })

    all和race方法

    all方法

    Promise.all 接收一个 promise对象的数组作为参数,当这个数组里的所有promise对象全部变为resolve或reject状态的时候,它才会去调用 .then 方法

    这个比较好用,当有多个请求的时候,一起请求,一起处理

        return new Promise(function(resolve,rejected){
            setTimeout(function(){
                resolve();
            },t)
        })
    }
    Promise.all([setTime(1000),setTime(5000)])
    .then(function(){
        console.log("5秒后打印!");
    })

    race方法

    只要有一个promise对象进入 FulFilled 或者 Rejected 状态的话,就会继续进行后面的处理。

    function setTime(t){
        return new Promise(function(resolve,rejected){
            setTimeout(function(){
                resolve();
            },t)
        })
    }
    Promise.race([setTime(1000),setTime(5000)])
    .then(function(){
        console.log("1秒后打印!");
    })

    一些用法的例子

    Promise并非所有的浏览器都支持,比如ie就是不支持,幸好jquery也有类似的用法

    1.一个异步里面接着另一个异步

    原生Promise的实现

    function setTime(t){
        return new Promise(function(resolve,reject){
            setTimeout(function(){
                resolve();
            },t)   
        });
    }
    setTime(1000)
        .then(function(){
            console.log(11111)
            return setTime(1000);
        })
        .then(function(){
            console.log(22222)
            return setTime(2000);
        })
        .then(function(){
            console.log(33333)
            return setTime(3000);
        })
        .then(function(){
            console.log(44444)
            return setTime(4000);
        })
        .then(function(){
            console.log(55555)
        })    

    jquery的实现

    function setTime(t){
        return $.Deferred(function(dtd){
            setTimeout(function(){
                dtd.resolve();
            },t);
        });
    }
    
    setTime(2000)
        .then(function(){
            console.log(11111)
            return setTime(1000);
        })
        .then(function(){
            console.log(22222)
            return setTime(2000);
        })
        .then(function(){
            console.log(33333)
            return setTime(3000);
        })
        .then(function(){
            console.log(44444)
            return setTime(4000);
        })
        .then(function(){
            console.log(55555)
        })

    2.多个ajax串行的请求(满足后面的请求依赖前面的请求的情况)

    原生的实现

    chorme浏览器可以直接在博客园下的console直接运行,如果接口都还在的

    var urls = {
        sideRight : "http://www.cnblogs.com/aggsite/SideRight",
        userStats : "http://www.cnblogs.com/aggsite/UserStats"
    }
    function get(URL){
        return new Promise(function (resolve, reject) {
            var req = new XMLHttpRequest();
            req.open('GET', URL, true);
            req.onload = function () {
                if (req.status === 200) {
                    resolve(req.responseText);
                } else {
                    reject();
                }
            };
            req.onerror = function () {
                reject();
            };
            req.send();        
        });
    }
    get(urls.sideRight)
        .catch(function(){
            console.log("请求失败!!!");
        })
        .then(function(html){
            console.log(html);
            console.log("-----------------------------------------------------------")
            return get(urls.userStats);
        })
        .catch(function(){
            console.log("请求失败!!!");
        })
        .then(function(html){
            console.log(html)
        })

    jquery的实现

    var urls = {
        sideRight : "http://www.cnblogs.com/aggsite/SideRight",
        userStats : "http://www.cnblogs.com/aggsite/UserStats"
    }
    
    $.ajax({
            url      : urls.sideRight,
            type     : "get",
            dataType : "html"
        })
        .fail(function(){
            console.log("请求失败!!!");
        })
        .done(function(html){
            console.log(html)
            console.log("-----------------------------------------------------------")
            return $.ajax({
                        url      : urls.userStats,
                        type     : "get",
                        dataType : "html"
                    });
        })
        .fail(function(){
            console.log("请求失败!!!");
        })
        .done(function(html){
            console.log(html)
        })

    3.多个请求并行发送(适用于多个请求才能渲染出一个页面的情况)

    原生Promise实现

    var urls = {
        sideRight : "http://www.cnblogs.com/aggsite/SideRight",
        userStats : "http://www.cnblogs.com/aggsite/UserStats"
    }
    function get(URL){
        return new Promise(function (resolve, reject) {
            var req = new XMLHttpRequest();
            req.open('GET', URL, true);
            req.onload = function () {
                if (req.status === 200) {
                    resolve(req.responseText);
                } else {
                    reject(URL);
                }
            };
            req.onerror = function () {
                reject(URL);
            };
            req.send();        
        });
    }
    
    Promise.all([get(urls.sideRight),get(urls.userStats)])
        .then(function(htmlArr){
            console.log(htmlArr[0])
            console.log("-----------------------------------------------------------")
            console.log(htmlArr[1])
        })
        .catch(function(url){
            console.log(url+"  : 失败了");
        })

    jquery实现

    var urls = {
        sideRight : "http://www.cnblogs.com/aggsite/SideRight",
        userStats : "http://www.cnblogs.com/aggsite/UserStats1"
    }
    
    var $ajax1 = $.ajax({
        url      : urls.sideRight,
        type     : "get",
        dataType : "html"
    })
    
    var $ajax2 = $.ajax({
        url      : urls.userStats,
        type     : "get",
        dataType : "html"
    })
    
    $.when($ajax1,$ajax2)
        .done(function(response1Arr,response2Arr){
            console.log(response1Arr[0]);
            console.log("----------------------------");
            console.log(response2Arr[1])
        })
        .fail(function(res){
            console.log("请求失败了")
        });

    注:当任意一个请求失败的时候,都会进入fail

  • 相关阅读:
    两种选择排序法
    三种方法求组合偶数字
    sizeof和mallo
    多态的概念与接口重用
    Delphi Exception的理解
    给老婆留着
    Delphi 一个简单的DELPHI自定义事件的例子
    Delphi 纯Pascal编写的程序,没有通过VCL
    Delphi 继承类的构造函数和析构函数的构建顺序
    Delphi 对象间数据的复制
  • 原文地址:https://www.cnblogs.com/wtcsy/p/promise.html
Copyright © 2011-2022 走看看