概述
为了体验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比较符合实际业务,所以我们只实现情况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。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。