zoukankan      html  css  js  c++  java
  • 把ajax包装成promise的形式(1)

    概述

    为了体验promise的原理,我打算自己把ajax包装成promise的形式。主要希望实现下列功能:

    // 1.使用success和error进行链式调用,并且可以在后面加上无限个
    promise.get(myUrl).success(successCallback1).error(errorCallback1).success(successCallback2).error(errorCallback2).error(errorCallback3).success(successCallback3);
    
    // 2.支持同时调用多个myUrl,这个时候需要最后的http请求返回之后才执行回调。
    promise.get(myUrl1).success(successCallback1).get(myUrl2).error(errorCallback1).get(myUrl3).error(errorCallback2).success(successCallback1);
    
    // 3.支持post和jsonp请求。
    

    对于ajax我选用jq的ajax,但是尽量不使用jq的deferred对象。
    本篇博文完成功能1,其它功能在其它博文完成。

    功能一

    初看功能一,我们有如下思路

    1. 建立一个构造函数,它的原型方法有get(发出get请求),success(挂载成功函数回调),error(挂载失败函数回调);
    2. 这个构造函数有一个原型对象,来分别储存成功和失败的回调函数。
    3. get请求里面发出ajax,并依次执行原型对象的成功和失败回调函数。
    let Promise = function() {
        this.eventName = {
            success: [],
            error: []
        };
    };
    
    Promise.prototype.success = function(cb) {
        this.eventName.success.push(cb);
        return this;
    };
    
    Promise.prototype.error = function(cb) {
        this.eventName.error.push(cb);
        return this;
    };
    
    Promise.prototype.get = function(url) {
        let that = this;
        $.ajax({
            url: url,
            type: 'get',
            timeout: 5000,
            success: function (data, status) {
                let successList = that.eventName.success;
                if(successList || successList.length) {
                    for(let i = 0; i < successList.length; i++) {
                        successList[i](data, status);
                    }
                }
            },
            error: function (err, status) {
                let errorList = that.eventName.error;
                if(errorList || errorList.length) {
                    for(let i = 0; i < errorList.length; i++) {
                        errorList[i](err, status);
                    }
                }
            }
        });
        return this;
    };
    

    然后我们可以执行:

    let successCallback1 = (data, status) => {
        console.log(data);
    }
    
    let successCallback2 = (data, status) => {
        console.log(data);
    }
    
    let errorCallback1 = (err, status) => {
        console.log(data);
    }
    
    let errorCallback2 = (err, status) => {
        console.log(data);
    }
    
    let url = 'xxxxxxxxxx';
    let promise = new Promise();
    promise.success(successCallback1)
           .error(errorCallback1)
           .error(errorCallback2)
           .success(successCallback2)
           .get(url);
    

    但是这样有一个缺点,就是get方法只能在最后调用,不能提到前面来。

    怎么提到前面来变成下面的调用形式呢?

    promise.get(url)
           .success(successCallback1)
           .error(errorCallback1)
           .error(errorCallback2)
           .success(successCallback2);
    

    思考可以用setTimeout,测试代码如下:

    var Haha = function() {
        this.a = [];
    };
    
    Haha.prototype.go = function() {
        setTimeout(() => {
            this.a.push(1);
            let that = this;
            setTimeout(() => {
                that.a.push(2);
            });
        });
        return this;
    };
    
    Haha.prototype.push = function(ele) {
        this.a.push(ele);
        return this;
    };
    
    var yaya = new Haha();
    
    yaya.go().push(3).push(4);
    // 过一段时间再打印yaya.a,可以看到输出[3, 4, 1, 2]
    

    所以类似的,我们可以把get方法修改如下:

    Promise.prototype.get = function() {
        setTimeout(() => {
            let that = this;
            $.ajax({
                url: myUrl,
                type: 'get',
                timeout: 5000,
                success: function (data, status) {
                    let successList = that.eventName.success;
                    if(successList || successList.length) {
                        for(let i = 0; i < successList.length; i++) {
                            successList[i](data, status);
                        }
                    }
                },
                error: function (err, status) {
                    let errorList = that.eventName.error;
                    if(errorList || errorList.length) {
                        for(let i = 0; i < errorList.length; i++) {
                            errorList[i](err, status);
                        }
                    }
                }
            });
        }, 0);
        return this;
    }
    

    目测可行,之后找个时间测试一下。

  • 相关阅读:
    IE10、IE11下SCRIPT5009: “__doPostBack”未定义
    CSS Hack大全-可区分出IE6-IE10、FireFox、Chrome、Opera
    HTML head 头标签
    html5匹配不同分辨率样式
    html5关键帧动画,一个小例子快速理解关键帧动画
    导入Excel到数据库
    JavaScript树(一) 简介
    深入解析浏览器的幕后工作原理(五) 呈现树
    深入解析浏览器的幕后工作原理(四) DOM树
    深入解析浏览器的幕后工作原理(三) 呈现树和 DOM 树的关系
  • 原文地址:https://www.cnblogs.com/yangzhou33/p/9961097.html
Copyright © 2011-2022 走看看