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

    概述

    为了体验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对象。

    本篇博文实现功能2:多异步情形。

    多异步情形

    在多异步情形下,成功回调和失败回调的处理方式有如下情况:

    1. 成功回调接收所有参数,失败回调接收单一参数,只要失败,成功回调不执行,只执行相应失败回调。
    2. 成功回调接收所有参数,失败回调接收单一参数,就算失败,也执行成功回调。
    3. 成功回调接收所有参数,失败回调接收所有参数,就算失败,也执行成功回调。
    4. 等等。

    上面的情况都可以实现,但是只有情况1比较符合实际业务,所以我们只实现情况1.

    实现的方法是:我们引入一个哨兵变量,并且把返回的数据按顺序储存起来,用哨兵变量判断出最后一个成功返回后,表示数据全部返回,然后执行回调函数。

    代码如下:

    // 模拟ajax
    let mockAjax = ({ url, type, success, error }) => {
        let data = url + type, err = url + type, status;
        // 随机执行success或者error
        setTimeout(() => {
            let rand = Math.random() > 0.1;
            if(rand) {
                status = 1;
                if(typeof success == 'function') success(data, status);
            } else {
                status = 0;
                if(typeof error == 'function') error(err, status);
            }
        });
    }
    
    let Promise = function() {
        this.eventName = {
            success: [],
            error: []
        };
        // 返回数据的结果集合
        this.result = [];
        // 哨兵变量
        this.sum = 0;
        this.count = 0;
    };
    
    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 index = this.sum;
        this.sum ++;
        setTimeout(() => {
            let that = this;
            mockAjax({
                url: url,
                type: 'get',
                success: function (data, status) {
                    if(that.sum !== 0) {
                        that.result[index] = data;
                        that.count ++;
                        if(that.count == that.sum) {
                            let successList = that.eventName.success;
                            if(successList || successList.length) {
                                for(let i = 0; i < successList.length; i++) {
                                    successList[i](that.result, status);
                                }
                            }
                            // 初始化
                            that.result.length = 0;
                            that.sum = 0;
                            that.count = 0;
                        }
                    }
                },
                error: function (err, status) {
                    that.result.length = 0;
                    that.sum = 0;
                    that.count = 0;
                    let errorList = that.eventName.error;
                    if(errorList || errorList.length) {
                        for(let i = 0; i < errorList.length; i++) {
                            errorList[i](err, status);
                        }
                    }
                }
            });
        });
        return this;
    }
    
    // test===================
    let successCallback = (message) => (result, status) => {
        result.map(ele => {
            console.log(ele + '成功回调' + message);
        });
    }
    let errorCallback = (message) => (err, status) => {
        console.log(err + '失败回调' + message);
    }
    
    let testPromise = new Promise();
    testPromise.get('url1').success(successCallback(1)).success(successCallback(2)).error(errorCallback(1)).error(errorCallback(2)).get('url2').success(successCallback(3)).error(errorCallback(3)).get('url3');
    

    测试输出结果如下:

    // 成功情况
    url1get成功回调1
    url2get成功回调1
    url3get成功回调1
    url1get成功回调2
    url2get成功回调2
    url3get成功回调2
    url1get成功回调3
    url2get成功回调3
    url3get成功回调3
    
    // 失败情况
    url1get失败回调1
    url1get失败回调2
    url1get失败回调3
    

    可以看到,成功情况,对返回的三个数据依次执行成功123;失败情况,只对失败的url1执行了失败回调123。

  • 相关阅读:
    Tableau如何绘制堆叠柱状图
    Tableau如何绘制多边形地图
    Tableau如何绘制凹凸图
    数据库备份策略设计
    MySQL数据库如何实现增量备份
    Tableau如何绘制瀑布图
    创建.net core ef项目
    asp.net core的ef的连接字符串
    sqlserver的varchar nvarchar区别
    jq的ajax请求写法
  • 原文地址:https://www.cnblogs.com/yangzhou33/p/9976839.html
Copyright © 2011-2022 走看看