概述

为了体验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, type, success, error }) => {
let data = url + type, err = url + type, status;
// 随机执行success或者error
setTimeout(() => {
let rand = Math.random() > 0.5;
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: []
};
}; 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全部返回之后再执行成功回调或者失败回调。

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

把ajax包装成promise的形式(2)的更多相关文章

  1. 把ajax包装成promise的形式(3)

    概述 为了体验promise的原理,我打算自己把ajax包装成promise的形式.主要希望实现下列功能: // 1.使用success和error进行链式调用,并且可以在后面加上无限个 promis ...

  2. 把ajax包装成promise的形式(1)

    概述 为了体验promise的原理,我打算自己把ajax包装成promise的形式.主要希望实现下列功能: // 1.使用success和error进行链式调用,并且可以在后面加上无限个 promis ...

  3. 如何把 Callback 接口包装成 Promise 接口

    最近一段时间一直在看Node.js,在开发过程中经常要调用一些异步接口,通常在接口的最后一个参数会传入一个回调函数,可以用来处理异常,非异常情况.大致模式如下: var fs = require(“f ...

  4. Finder Item脚本如何包装成 Mac App

    第一步,包装 记得之前把一个 java 程序的 jar 包 用 automator包装成了 app, 但自己找不到做法了.回头我想了想 这么实验可行. 这样做成 app 后保存在 /Applicati ...

  5. (转)Groupon前传:从10个月的失败作品修改,1个月找到成功 并不挶泥在这个点子上面,它反而往后站一步,看看他们已经做好的这个网站,可以再怎么包装成另一个完完全全不同的网站?所有的人所做的每件失败的事情中, 一定有碰到或含有成功的答案」在里面,只是他们不知道而已。 人不怕失败」,只怕宣布失败」

    (转)Groupon前传:从10个月的失败作品修改,1个月找到成功 今天读到 一个非常励志人心的故事 ,就像现在「叶问」有「前传」,最近很火红的团集购网站Groupon 也出现了「Groupon前传」 ...

  6. SIP:用Riverbank的SIP创建C++库的Python模块(把自己的C++库包装成Python模块)

    我们发现PyQt做的Python版的PyQt是如此好用,如果想把自己的C++库包装成Python模块该如何实现呢? 这里介绍下用SIP包装C++库时值得参考的功能实现: 需要Python模块中实现C+ ...

  7. [Python] 将视频转成ASCII符号形式、生成GIF图片

    一.简要说明 简述:本文主要展示将视频转成ASCII符号形式展示出来,带音频. 运行环境:Win10/Python3.5. 主要模块: PIL.numpy.shutil. [PIL]: 图像处理 [n ...

  8. 安卓、ios时间转换成时间戳的形式

    将日期转换成时间戳的形式,在安卓和ios不同的系统下转正会有兼容性的问题 安卓系统下Date.parse(new Date('2018-03-30 12:00:00'))会直接转换成时间戳的形式(简单 ...

  9. Oracle中使用Table()函数解决For循环中不写成 in (l_idlist)形式的问题

    转: Oracle中使用Table()函数解决For循环中不写成 in (l_idlist)形式的问题 在实际PL/SQL编程中,我们要对动态取出来的一组数据,进行For循环处理,其基本程序逻辑为: ...

随机推荐

  1. python基础 (迭代器回顾,生成器,推导式)

    1.迭代器回顾 可迭代对象:Iterable 可以直接作用于for循环的对象统称为可迭代对象:Iterable.因为可迭代对象里面存在可迭代协议,所以才会被迭代 可迭代对象包括: 列表(list) 元 ...

  2. Lonsdor K518ISE SCION 2011-2018 Models Enabled!

    Lonsdor released the Lonsdor K518ISE Key Programmer update announcement on 14-03-2019, saying it can ...

  3. L2范数的相关求解

    https://blog.csdn.net/u010725283/article/details/79212762

  4. Python之路(第三十一篇) 网络编程:简单的tcp套接字通信、粘包现象

    一.简单的tcp套接字通信 套接字通信的一般流程 服务端 server = socket() #创建服务器套接字 server.bind() #把地址绑定到套接字,网络地址加端口 server.lis ...

  5. 一次性获取PPT图片方法

    XXX.ppt 改成 XXX.zip 或者 XXX.rar 解压,查看文件夹即可

  6. Java实现多线程生产者消费者模型及优化方案

    生产者-消费者模型是进程间通信的重要内容之一.其原理十分简单,但自己用语言实现往往会出现很多的问题,下面我们用一系列代码来展现在编码中容易出现的问题以及最优解决方案. /* 单生产者.单消费者生产烤鸭 ...

  7. DecimalFormat 的用法

    DecimalFormat 是 NumberFormat 的一个具体子类,用于格式化十进制数字. DecimalFormat 是 NumberFormat 的一个具体子类,用于格式化十进制数字.Dec ...

  8. linux系统下部署DNS反向解析

    DNS服务概述 DNS(Domain Name System)域名系统,能够提供域名与IP地址的解析服务. 反向解析 反向解析是从IP地址到域名的解析过程.主要作用于服务器的身份验证. 部署反向解析 ...

  9. version control

    what 版本控制最主要的功能就是追踪文件的变更.它将什么时候.什么人更改了文件的什么内容等信息忠实地了已录下来.每一次文件的改变,文件的版本号都将增加.除了记录版本变更外,版本控制的另一个重要功能是 ...

  10. Spring Boot的Maven配置

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...