如何利用Promises使$.ajax()按顺序发起多个请求更简单

0.写在前面

众所周知,Promise是在ES6中新增的异步编程的一种解决方案。而Promise的一些基础用法可以参考一下阮一峰老师的ES6入门。本文主要介绍如何利用Promises使$.ajax()按顺序发起多个请求。

本文的一些代码主要参考了JavaScript Promise迷你书

1.Promise.resolve

一般情况下我们都会使用 new Promise() 来创建promise对象,但是除此之外我们也可以使用其他方法。

静态方法Promise.resolve(value) 可以认为是 new Promise() 方法的快捷方式。

比如 Promise.resolve(42); 可以认为是以下代码的语法糖。

	new Promise(function(resolve){
	    resolve(42);
	});

在这段代码中的 resolve(42); 会让这个promise对象立即进入确定(即resolved)状态,并将 42 传递给后面then里所指定的 onFulfilled 函数。

方法 Promise.resolve(value); 的返回值也是一个promise对象,所以我们可以像下面那样接着对其返回值进行 .then 调用。

	Promise.resolve(42).then(function(value){
	    console.log(value);
	});

2.Promise 方法链

promise可以写成方法链的形式

	function taskA() {
    	console.log("Task A");
	}
	function taskB() {
	    console.log("Task B");
	}
	function onRejected(error) {
	    console.log("Catch Error: A or B", error);
	}

	function finalTask() {
	    console.log("Final Task");
	}
	
	var promise = Promise.resolve();
	promise
	    .then(taskA)
	    .then(taskB)
	    .catch(onRejected)
	    .then(finalTask);

上面的Promise方法链的执行流程图如下
在这里插入图片描述

若在执行时遇到错误,或返回一个onRejected对象,就会执行catch中的代码,然后在执行完catch后,就会进入到finalTask中。

若在执行时未遇到错误或未返回onRejected对象,就会按下面的顺序依次执行:TaskA => TaskB => FinalTask

3.Promise 方法链中如何传递参数

前面例子中的Task都是相互独立的,只是被简单调用而已。

这时候如果 Task A 想给 Task B 传递一个参数该怎么办呢?

答案非常简单,那就是在 Task A 中 return 的返回值,会在 Task B 执行时传给它。

话不多说,上代码

	function doubleUp(value) {
	    return value * 2;
	}
	function increment(value) {
	    return value + 1;
	}
	function output(value) {
	    console.log(value);// => (1 + 1) * 2
	}
	
	var promise = Promise.resolve(1);
	promise
	    .then(increment)
	    .then(doubleUp)
	    .then(output)
	    .catch(function(err){
	        // promise chain中出现异常的时候会被调用
	        console.error(err);
	    });

这段代码的入口函数是 Promise.resolve(1); ,整体的promise chain执行流程如下所示。

  1. Promise.resolve(1); 传递 1 给 increment 函数

  2. 函数 increment 对接收的参数进行 +1 操作并返回(通过return)

  3. 这时参数变为2,并再次传给 doubleUp 函数

  4. 最后在函数 output 中打印结果

4.用Promise转换thenable对象

Promise.resolve 方法另一个作用就是将 thenable 对象转换为promise对象。

所谓的thenable对象就像是类数组(Array Like)对象一样,thenable是指一个具有.then方法的对象。

这种将thenable对象转换为promise对象的机制要求thenable对象所拥有的 then 方法应该和Promise所拥有的 then 方法具有同样的功能和处理过程,在将thenable对象转换为promise对象的时候,还会巧妙的利用thenable对象原来具有的 then 方法。

到底什么样的对象能算是thenable的呢,最简单的例子就是 jQuery.ajax(),它的返回值就是thenable的。

因为jQuery.ajax() 的返回值是 jqXHR Object 对象,这个对象具有 .then 方法。

	$.ajax(url,parse); // 这个方法的返回值就是一个thenable对象

这个thenable的对象可以使用 Promise.resolve 来转换为一个promise对象。

变成了promise对象的话,就能直接使用 then 或者 catch 等这些在 ES6 Promises里定义的方法了。

5.Promise结合$.ajax()实战

由于$.ajax的返回值是一个典型的thenable对象,所以我们可以通过结合Promise与$.ajax()来使通过$.ajax()发起请求更加方便

代码演示如下:

	//  这里只设置三个最基本的配置用于演示,而且不用写success
	function api(option) { 				 //option是一个对象,用于配置参数
		return Promise.resolve($.ajax({
			type: option.type,
			url: option.url,
			data: option.data
		}))
	}

若需要添加后续操作,也是十分的简单

	var option =
	 {
		type: 'post',
		url: 'baidu.com',
		data: {
			a: 123
		}
	 }
	api(option)
		.then((res) => {
			console.log(res) //  将success里面的操作放到这里
		})
		.catch((err) => {
			console.log(err)  //  发生错误或返回一个Rejected状态的promise时在这里进行处理
		})

若为了使代码便于阅读,可以改写成这样

	var option =
	 {
		type: 'post',
		url: 'baidu.com',
		data: {
			a: 123
		}
	 };
	function postSuccess (res) {
		console.log(res)  //  将success里面的操作放到这里
	}
	function postErr(err) {
		console.log(err)  //  发生错误或返回一个Rejected状态的promise时在这里进行处理
	}
	
	api(option)
		.then(postSuccess)
		.catch(postErr)

重点来了,如果需要按顺序发起多个请求,可以改造成下面的样子

	var option =
	 {
		type: 'post',
		url: 'baidu.com',
		data: {
			a: 123
		}
	 };
	function taskASuccess(res) {
		console.log(res)  //  将success里面的操作放到这里
		var option = {
			//  可以在这里定义想要传递给taskB的参数,并通过后面的return传递
		}
		return option
	}
	function taskB(opt) {
		return api(opt)
	} 
	function taskBSuccess(res) {
		console.log(res)  
	}
	
	api(option)
		.then(taskASuccess)
		.then(taskB)
		.then(taskBSuccess) //  若想发起更多请求可以以此类推
		.catch((err) => {
			console.log(err)
		})

看完上面的代码,是不是感觉比传统的回调函数便于阅读多了,若您觉得本篇文章对您有帮助,请帮忙点个关注!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值