如何利用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)
		})

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果要在 React 中发送多个 mtop 请求,并使用 Promise.allSettled() 方法来等待所有请求完成,可以按照以下步骤操作: 1. 安装 mtop-sdk,可以使用 npm 进行安装:`npm install mtop-sdk --save`。 2. 在组件中使用 mtop-sdk 发送多个请求。可以将请求的参数存储在一个数组中,并使用 Array.map() 方法将它们转换为 Promise 对象,然后将这些 Promise 对象传递给 Promise.allSettled() 方法。示例代码如下: ```jsx import React, { useEffect, useState } from "react"; import Mtop from "mtop-sdk"; function App() { const [data, setData] = useState([]); async function fetchData() { const apiList = [ { api: "api1", v: "1.0", data: { id: 1 } }, { api: "api2", v: "1.0", data: { id: 2 } }, { api: "api3", v: "1.0", data: { id: 3 } } ]; const promises = apiList.map(api => { return new Promise((resolve, reject) => { Mtop.request({ api: api.api, v: api.v, data: api.data, success: response => { resolve(response); }, error: error => { reject(error); } }); }); }); const responses = await Promise.allSettled(promises); const newData = responses .filter(response => response.status === "fulfilled") .map(response => response.value.data); setData(newData); } useEffect(() => { fetchData(); }, []); return ( <div> {data.map(item => ( <div key={item.id}>{item.name}</div> ))} </div> ); } export default App; ``` 在上面的代码中,我们首先定义了一个 fetchData() 函数,该函数会发送多个 mtop 请求,并使用 Promise.allSettled() 方法来等待所有请求都完成。然后,我们使用 Array.map() 方法将每个请求的参数转换为一个 Promise 对象,并将这些 Promise 对象存储在 promises 数组中。接下来,我们通过循环调用 Mtop.request() 方法来发送每个请求,并将请求的结果存储在对应的 Promise 对象中。最后,我们使用 Promise.allSettled() 方法来等待所有请求完成,并过滤出已成功解决的 Promise 对象。在处理 responses 数组时,我们首先过滤出已成功解决的 Promise 对象,然后将它们的数据提取出来,并存储在 newData 数组中。最后,我们使用 newData 数组来新组件的状态,从而渲染数据。 需要注意的是,Mtop.request() 方法是一个异步方法,因此我们需要将它封装在一个 Promise 对象中,以便它可以与其他 Promise 对象一起被 Promise.allSettled() 方法等待。在处理 responses 数组时,我们可以通过检查 Promise 对象的 status 属性来确定该 Promise 对象是解决(fulfilled)还是拒绝(rejected),并提取对应的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值