加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

把ajax包装成promise(2)

发布时间:2020-12-16 03:00:21 所属栏目:百科 来源:网络整理
导读:概述 为了体验promise的 原理 ,我打算自己把ajax包装成promise。主要希望实现下列功能: // 1.使用success和error进行链式调用,并且可以在后面加上无限个promise.get(myUrl).success(successCallback1).error(errorCallback1).success(successCallback2).e

概述

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

本篇博文实现一个测试用ajax方法

测试用ajax

因为用实际ajax接口非常不方便测试,所以我用setTimeout模拟了一个ajax方法进行测试用。

值得一提的是,如果在node端,建议使用setImmediate代替setTimeout会有更好的性能。目前浏览器端只有IE支持setImmediate。

// 模拟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);
        }
    });
}

mockAjax随机进行成功或者失败返回,可以更改上面的0.1来调高或者调低相关概率。

需要说明的是,最好在chrome的开发者工具下运行上面的代码,其它浏览器可能不支持参数解构

使用mockAjax进行测试

// 模拟ajax
let mockAjax = ({ url,status;
    // 随机执行success或者error
    setTimeout(() => {
        let rand = Math.random() > 0.5;
        if(rand) {
            status = 1;
            if(typeof success == 'function') success(data,status);
        }
    });
}

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;
    setTimeout(() => {
        mockAjax({
            url: url,type: 'get',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;
};

// test===================
let successCallback = (message) => (data,status) => {
    console.log(data + '成功回调' + 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));

可以看到浏览器输出如下:

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

多异步协作

多异步情况下会返回什么呢?

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
url1get成功回调2
url1get成功回调3
url2get成功回调1
url2get成功回调2
url2get成功回调3
url3get失败回调1
url3get失败回调2
url3get失败回调3

冷静分析,在url1返回的时候,url2和url3没有返回,此时对url1返回的数据执行了三个成功回调。

但是更多情况下,我们需要url1,url2,url3全部返回之后再执行成功回调或者失败回调。

这种功能我们将在下篇博文实现。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读