update: Promise 链式调用

This commit is contained in:
qianguyihao 2020-04-08 16:20:38 +08:00
parent 3b16461b0d
commit 5e3679a89c

View File

@ -156,13 +156,13 @@ Promise对象, 可以**将异步操作以同步的流程表达出来**。使用
) )
``` ```
## 【重要】基于 Promise 处理 多次 Ajax 请求(链式调用) ## 基于 Promise 处理 多次 Ajax 请求(链式调用)【重要】
实际开发中,我们经常需要同时请求多个接口。比如说:在请求完`接口1`的数据`data1`之后,需要根据`data1`的数据继续请求接口2获取`data2`;然后根据`data2`的数据继续请求接口3。 实际开发中,我们经常需要同时请求多个接口。比如说:在请求完`接口1`的数据`data1`之后,需要根据`data1`的数据继续请求接口2获取`data2`;然后根据`data2`的数据继续请求接口3。
这种场景其实就是接口的多层嵌套调用。有了 promise之后我们可以把多层嵌套调用按照**线性**的方式进行书写,非常优雅 换而言之现在有三个网络请求请求2必须依赖请求1的结果请求3必须依赖请求2的结果如果按照往常的写法会有三层回调会陷入“回调地狱”
也就是说Promise 可以把原本的**多层嵌套调用**改进为**链式调用**。 这种场景其实就是接口的多层嵌套调用。有了 Promise 之后,我们可以把多层嵌套调用按照**线性**的方式进行书写,非常优雅。也就是说Promise 可以把原本的**多层嵌套调用**改进为**链式调用**。
代码举例:(多次 Ajax请求链式调用 代码举例:(多次 Ajax请求链式调用
@ -175,67 +175,74 @@ Promise对象, 可以**将异步操作以同步的流程表达出来**。使用
<title>Document</title> <title>Document</title>
</head> </head>
<body> <body>
<script type="text/javascript"> <script>
/* const request = require('request');
基于Promise发送Ajax请求
*/ // Promise 封装接口
function queryData(url) { const request1 = function() {
var promise = new Promise((resolve, reject) => { const promise = new Promise(resolve => {
var xhr = new XMLHttpRequest(); request('https://www.baidu.com', function(response) {
xhr.onreadystatechange = function() { if (response.retCode == 200) {
if (xhr.readyState != 4) return; resolve('request1 success');
if (xhr.readyState == 4 && xhr.status == 200) {
// 处理正常情况
resolve(xhr.responseText); // xhr.responseText 是从接口拿到的数据
} else { } else {
// 处理异常情况
reject('接口请求失败'); reject('接口请求失败');
} }
}; });
xhr.responseType = 'json'; // 设置返回的数据类型
xhr.open('get', url);
xhr.send(null); // 请求接口
}); });
return promise; return promise;
} };
// 发送多个ajax请求并且保证顺序
queryData('http://localhost:3000/api1') const request2 = function() {
.then( const promise = new Promise(resolve => {
data1 => { request('https://www.jd.com', function(response) {
console.log(JSON.stringify(data1)); if (response.retCode == 200) {
// 请求完接口1后继续请求接口2 resolve('request2 success');
return queryData('http://localhost:3000/api2'); } else {
}, reject('接口请求失败');
error1 => { }
console.log(error1); });
} });
)
.then( return promise;
data2 => { };
console.log(JSON.stringify(data2));
// 请求完接口2后继续请求接口3 const request3 = function() {
return queryData('http://localhost:3000/api3'); const promise = new Promise(resolve => {
}, request('https://www.taobao.com', function(response) {
error2 => { if (response.retCode == 200) {
console.log(error2); resolve('request3 success');
} } else {
) reject('接口请求失败');
.then( }
data3 => { });
// 获取接口3返回的数据 });
console.log(JSON.stringify(data3));
}, return promise;
error3 => { };
console.log(error3);
} // 先发起request1等resolve后再发起request2紧接着等 request2有了 resolve之后再发起 request3
); request1()
.then(data => {
console.log(data);
return request2();
})
.then(data => {
console.log(data);
return request3();
})
.then(data => {
console.log(data);
});
</script> </script>
</body> </body>
</html> </html>
``` ```
上面这个举例很经典,需要多看几遍。 上面代码中then是可以链式调用的后面的then可以拿到前面resolve出来的数据。
这个举例很经典,需要多看几遍。
## return 的函数返回值 ## return 的函数返回值
@ -502,7 +509,7 @@ Promise 自带的API提供了如下对象方法
- Promise.race(): 并发处理多个异步任务,只要有一个任务执行成功,就能得到结果。 - Promise.race(): 并发处理多个异步任务,只要有一个任务执行成功,就能得到结果。
下面来详细介绍 下面来详细介绍
### Promise.all() 代码举例 ### Promise.all() 代码举例
@ -539,9 +546,9 @@ Promise 自带的API提供了如下对象方法
}); });
} }
var promise1 = queryData('http://localhost:3000/a1'); var promise1 = queryData('http://localhost:3000/api1');
var promise2 = queryData('http://localhost:3000/a2'); var promise2 = queryData('http://localhost:3000/api2');
var promise3 = queryData('http://localhost:3000/a3'); var promise3 = queryData('http://localhost:3000/api3');
Promise.all([promise1, promise2, promise3]).then(result => { Promise.all([promise1, promise2, promise3]).then(result => {
console.log(result); console.log(result);
@ -551,7 +558,6 @@ Promise 自带的API提供了如下对象方法
</html> </html>
``` ```
### Promise.race() 代码举例 ### Promise.race() 代码举例
代码举例: 代码举例:
@ -587,9 +593,9 @@ Promise 自带的API提供了如下对象方法
}); });
} }
var promise1 = queryData('http://localhost:3000/a1'); var promise1 = queryData('http://localhost:3000/api1');
var promise2 = queryData('http://localhost:3000/a2'); var promise2 = queryData('http://localhost:3000/api2');
var promise3 = queryData('http://localhost:3000/a3'); var promise3 = queryData('http://localhost:3000/api3');
Promise.race([promise1, promise2, promise3]).then(result => { Promise.race([promise1, promise2, promise3]).then(result => {
console.log(result); console.log(result);
@ -599,13 +605,13 @@ Promise 自带的API提供了如下对象方法
</html> </html>
``` ```
了解这些内容之后, Promise 的基本用法,你就已经掌握了。
## 参考链接 ## 参考链接
- [当面试官问你Promise的时候他究竟想听到什么](https://zhuanlan.zhihu.com/p/29235579) - [当面试官问你Promise的时候他究竟想听到什么](https://zhuanlan.zhihu.com/p/29235579)
- [手写一个Promise/A+,完美通过官方872个测试用例](https://www.cnblogs.com/dennisj/p/12660388.html)
## 我的公众号 ## 我的公众号
@ -616,5 +622,3 @@ Promise 自带的API提供了如下对象方法
![](http://img.smyhvae.com/20200101.png) ![](http://img.smyhvae.com/20200101.png)