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

概述

为了体验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全部返回之后再执行成功回调或者失败回调。

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

原文地址:https://www.cnblogs.com/yangzhou33/p/9976171.html

时间: 2024-08-30 07:22:57

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

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

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

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

最近一段时间一直在看Node.js,在开发过程中经常要调用一些异步接口,通常在接口的最后一个参数会传入一个回调函数,可以用来处理异常,非异常情况.大致模式如下: 1 var fs = require(“fs"); 2 fs.readFile(filename, "binary", function(err, file){ 3 if(err){ 4 //异常情况 5 }else{ 6 //正常情况 7 } 8 }); 但是,这种写法遇上比较复杂的逻辑时,就很容易出现 callb

将Python脚本文件包装成可执行文件

将Python脚本文件包装成可执行文件,其目的有二: 一则: 不需要依赖Python编译器就可以运行软件 二则: 不想让自己的源码公布出去 常用的工具有: py2exe.cx_freeze等 [工具:py2exe] 安装py2exe 安装该工具很简单: 只需要从官方网站:http://www.py2exe.org/下载与版本对应的安装程序,点击下一步即可完成安装. 安装后,执行import py2exe,不报错则表示安装成功! >>> import py2exe >>>

将python的程序包装成windows下的service

使用python编写的脚本应用程序,在运行的时候需要有python的运行环境,但是我们肯定是希望整个python程序能够像应用程序一样打包生成一个包括其运行环境的exe文件包,这是第一步,但是要想使用net start这样的方式启动, 还需要将该exe注册到服务里面去,使用exe install完成. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #SmallestService.py 

将日期类型转换成年月日的形式

如题. 1 namespace sanyuandemo 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 DateTime dateTime = DateTime.Parse("2014-05-19"); 8 string str = dateTime.ToString("yyyy年M月dd日"); 9 Console.WriteLine(str); 10 Console.Read();

NSValue (将结构体包装成NSValue)

将结构体包装成 NSValue ,并取出结构体 1 NSRect rect = {0, 0, 200,200}; 2 NSValue *rectValue = [NSValue valueWithBytes:&rect objCType:@encode(NSRect)]; 3 NSRect newRect; 4 [rectValue getValue:&newRect]; 5 NSLog(@"%f,%f,%f,%f",newRect.origin.x,newRect.o

爪哇国新游记之二十----将数字转换成汉子大写形式

/** * 辅助类 * 用于记载字符和位置 * */ class CharPos{ char c; int pos; public CharPos(char c,int pos){ this.c=c; this.pos=pos; } } /** * 将数字转化成汉字大写形式 * */ public class CnNumMaker { private String integerPart;// 整数部分 private String decimalPart;// 小数部分 private Sta

完美释放实例变量的内存,定义成宏的形式

完美释放内存,麻烦自己方便他人... 定义成宏的形式: #define RELEASE_SAFE(_Pointer) do{[_Pointer release],_Pointer = nil;}while(0)  例: //姓名 @property (nonatomic,copy)NSString *name; //性别 @property (nonatomic,copy)NSString *gender; //年龄 @property (nonatomic,copy)NSString *age

把h264文件快速包装成mp4格式

mkv里封装的.h264文件提取出来后,不能直接导入到premiere等视频编辑软件里,需要转换成mp4文件. 这里介绍如何把封装在 mkv 里面的 .h264 视频文件转换为 mp4 格式.(只有视频,不含音频) 此种方法速度快,比用格式转换软件 mkv 转 mp4 快很多. 用到的工具:MKVExtractGUI.2.3.0.0.简体汉化版 //从mkv文件里提取出.h264文件.(此软件需搭配主体程序:MKVToolNix)My MP4Box GUI //把.h264文件包装成mp4文件.