ES6之Promise实战,让你的多次请求更清晰
Posted lovoo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6之Promise实战,让你的多次请求更清晰相关的知识,希望对你有一定的参考价值。
前言
在实际开发中,我们经常会在发送一个请求后,得到反馈,再进行一下次请求,再得到反馈,又再进行下一次请求,每次的代码都在ajax内部的success实现,这样看起来繁琐,容易造成数据通信堵塞。如何解决这个问题呢?这时我们就可以利用Promise来解决!
在开始深入学习Promise前,熟悉JS Event Loop的机制是非常有必要的,如果你对Event Loop还不熟悉,非常推荐你先阅读javascript之多线程和Event Loop这篇文章,会对你更好理解Promise执行顺序帮助很大!
什么是Promise?
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
古人云:“君子一诺千金”,所谓Promise,正如其中文含义,简单说就是一个承诺,“承诺将来会执行”约定的事情。
从语法上说,Promise 是一个对象,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
约定
不同于“老式”的传入回调,在使用 Promise 时,会有以下约定:
在本轮 Javascript event loop(事件循环)运行完成之前,回调函数是不会被调用的。
- 通过then()添加的回调函数总会被调用,即便它是在异步操作完成之后才被添加的函数。
- 通过多次调用then(),可以添加多个回调函数,它们会按照插入顺序一个接一个独立执行。
- 因此,Promise 最直接的好处就是链式调用(chaining)。
Promise的使用
一个Promise的三种状态
在开始使用Promise之前,我们首先需要了解Promise的三种状态:
pending: 初始状态,既不是成功,也不是失败状态。
fulfilled: 意味着操作成功完成。
rejected: 意味着操作失败。
pending 状态的 Promise 对象可能会变为fulfilled 状态并传递一个值给相应的状态处理方法,也可能变为失败状态(rejected)并传递失败信息。当其中任一种情况出现时,Promise 对象的 then 方法绑定的处理方法(handlers )就会被调用(then方法包含两个参数:onfulfilled 和 onrejected,它们都是 Function 类型。当Promise状态为fulfilled时,调用 then 的 onfulfilled 方法,当Promise状态为rejected时,调用 then 的 onrejected 方法, 所以在异步操作的完成和绑定处理方法之间不存在竞争)。
因为Promise.prototype.then和Promise.prototype.catch方法返回promise 对象, 所以它们可以被链式调用。
Promise实战
有这么个需求,根据查询某个用户的课程得分。
如下图,有三个json文件,首先请求用户获取用户,然后通用户id查询到其课程信息Id,然后根据课程Id,获取当前课程的得分
user.json:
{
"id": "1",
"name": "tom",
"age": 20
}
user_course_1.json
{
"id": "1",
"userId": "1",
"title": "java"
}
course_score_1.json
{
"id": "1",
"courseId": "1",
"score": 50
}
以前的实现方法
<script>
/**
* 1.查询当前用户信息
* 2.按照当前用户的id查出他的课程
* 3.按照当前课程id查询出分数
*/
$.ajax({
url:'mall-vue/src/views/demo/promise/user.json',
success(data){
$.ajax({
url:'mall-vue/src/views/demo/promise/user_coure_${data.id}.json',
success(data){
$.ajax({
url:'mall-vue/src/views/demo/promise/course_score_{data.id}.json',
success(data){
console.log(data.score)
},
error(err){
}
})
},
error(err){
}
})
},
error(err){
}
})
</script>
使用Promise实现
在每一次成功,才进行一下请求
const p = new Promise(function(resolve, reject) {
$.ajax({
url:'mall-vue/src/views/demo/promise/user.json',
success(data){
console.log("查询用户成功!=用户名称==", data.name)
resolve(data);
},
error(err){
reject(error);
}
})
p.then(function(data)){
return new Promise(function(resolve, reject) {
$.ajax({
url:'mall-vue/src/views/demo/promise/user_coure_${data.id}.json',
success(data){
console.log("查询课程成功!=课程名称==", data.title)
resolve(data);
},
error(err){
reject(error);
}
})
})
},function(error){
}
}).then(function(data){
$.ajax({
url:'mall-vue/src/views/demo/promise/course_score_{data.id}.json',
success(data){
console.log("查询分数成功!=分数==", data.score)
},
error(err){
}
})
})
将上述代码优化封装:
function get(url, data){
return new Promise((resolve, reject) => {
$.ajax({
url: url,
success(data){
resolve(data);
},
error(err){
reject(error);
}
})
})
}
得到简化版:
//上述代码简写:
get(`user.json`)
.then((data) => {
console.log("查询用户成功!=用户名称==", data)
return get(`user_course_${data.id}.json`)
})
.then((data) => {
console.log("查询课程成功!=课程名称==", data)
return get(`course_score_${data.id}.json`)
})
.then((data) => {
console.log("查询分数成功!=分数==", data)
})
.catch((err) => {
console.log("出现异常:", err)
})
以上是关于ES6之Promise实战,让你的多次请求更清晰的主要内容,如果未能解决你的问题,请参考以下文章