update: Promise 链式调用
This commit is contained in:
parent
3b16461b0d
commit
5e3679a89c
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user