网站建设成功案例书籍,可以做本地生活服务的有哪些网站,深圳技术支持 骏域网站建设,网站改版具体建议一、认识Promise
ES6中一个非常重要和好用的特性就是Promise
但是初次接触Promise会一脸懵逼#xff0c;这TM是什么东西#xff1f;看看官方或者一些文章对它的介绍和用法#xff0c;也是一头雾水。
Promise到底是做什么的呢#xff1f;
Promise是异步编程的一种解决方…一、认识Promise
ES6中一个非常重要和好用的特性就是Promise
但是初次接触Promise会一脸懵逼这TM是什么东西看看官方或者一些文章对它的介绍和用法也是一头雾水。
Promise到底是做什么的呢
Promise是异步编程的一种解决方案。
那什么时候我们会来处理异步事件呢
一种很常见的场景应该就是网络请求了。我们封装一个网络请求的函数因为不能立即拿到结果所以不能像简单的347一样将结果返回。所以往往我们会传入另外一个函数在数据请求成功时将数据通过传入的函数回调出去。如果只是一个简单的网络请求那么这种方案不会给我们带来很大的麻烦。
但是当网络请求非常复杂时就会出现回调地狱。 OK我以一个非常夸张的案例来说明。 我们来考虑下面的场景(有夸张的成分)
我们需要通过一个url1从服务器加载一个数据data1data1中包含了下一个请求的url2我们需要通过data1取出url2从服务器加载数据data2data2中包含了下一个请求的url3我们需要通过data2取出url3从服务器加载数据data3data3中包含了下一个请求的url4发送网络请求url4获取最终的数据data4 上面的代码有什么问题吗
正常情况下不会有什么问题可以正常运行并且获取我们想要的结果。但是这样额代码难看而且不容易维护。
我们更加期望的是一种更加优雅的方式来进行这种异步操作。 如何做呢
就是使用Promise。Promise可以以一种非常优雅的方式来解决这个问题。
二、Promise的基本使用
2.1 定时器的异步事件 我们先来看看Promise最基本的语法。 这里我们用一个定时器来模拟异步事件
假设下面的data是从网络上1秒后请求的数据console.log就是我们的处理方式。
上图是我们过去的处理方式我们将它换成Promise代码 这个例子会让我们感觉脱裤放屁多此一举
首先下面的Promise代码明显比上面的代码看起来还要复杂。其次下面的Promise代码中包含的resolve、reject、then、catch都是些什么东西
我们先不管第一个复杂度的问题因为这样的一个屁大点的程序根本看不出来Promise真正的作用。
2.2 定时器异步事件解析
我们先来认认真真的读一读这个程序到底做了什么
new Promise很明显是创建一个Promise对象小括号中((resolve, reject) {})也很明显就是一个函数而且我们这里用的是之前刚刚学习过的箭头函数。
但是resolve, reject它们是什么呢
我们先知道一个事实在创建Promise时传入的这个箭头函数是固定的一般我们都会这样写resolve和reject它们两个也是函数通常情况下我们会根据请求数据的成功和失败来决定调用哪一个。
成功还是失败
如果是成功的那么通常我们会调用resolve(messsage)这个时候我们后续的then会被回调。如果是失败的那么通常我们会调用reject(error)这个时候我们后续的catch会被回调。
OK这就是Promise最基本的使用了。
!DOCTYPE html
html langen
headmeta charsetUTF-8titleTitle/title
/head
bodyscript// 1.使用setTimeout// setTimeout(() {// console.log(Hello world!);// }, 1000)// new Promise(参数) 参数-函数resolve,reject// resolve,reject它们本身又是函数// 链式编程/*new Promise((resolve,reject) {// 第一次发生网络请求的代码setTimeout(() {// console.log(Hello world!);resolve()}, 1000)}).then(() {// 第一次拿到结果后的处理代码console.log(Hello world!);console.log(Hello world!);return new Promise((resolve, reject) {// 第二次发生网络请求的代码setTimeout(() {resolve()}, 1000)}).then(() {// 第二次拿到结果后的处理代码console.log(Hello vuejs!);console.log(Hello vuejs!);return new Promise((resolve, reject) {// 第三次发生网络请求的代码setTimeout(() {resolve()}, 1000)}).then(() {// 第三次拿到结果后的处理代码console.log(Hello promise!);console.log(Hello promise!);})})})*/// 什么情况下会用到Promise// 一般情况下是有异步操作时会使用Promise对这个异步操作进行封装new Promise((resolve, reject) {setTimeout(() {// 成功的时候调用resolve// resolve(hello data)// 失败的时候调用rejectreject(error message)}, 1000)}).then((data) {console.log(data);console.log(data);console.log(data);console.log(data);}).catch((err) {console.log(err);})/script
/body
/htmlthen()处理成功catch()处理失败 不写catch(),把处理成功和失败的两个函数都作为then()函数的参数传进去
三、Promise三种状态
首先, 当我们开发中有异步操作时, 就可以给异步操作包装一个Promise
异步操作之后会有三种状态我们一起来看一下这三种状态:
pending等待状态比如正在进行网络请求或者定时器没有到时间。fulfill满足状态当我们主动回调了resolve时就处于该状态并且会回调.then()reject拒绝状态当我们主动回调了reject时就处于该状态并且会回调.catch() 四、Promise的链式编程 !DOCTYPE html
html langen
headmeta charsetUTF-8titleTitle/title
/head
body
script// 1.使用setTimeout// setTimeout(() {// console.log(Hello world!);// }, 1000)// new Promise(参数) 参数-函数resolve,reject// resolve,reject它们本身又是函数// 链式编程new Promise((resolve,reject) {// 第一次发生网络请求的代码setTimeout(() {// console.log(Hello world!);resolve()}, 1000)}).then(() {// 第一次拿到结果后的处理代码console.log(Hello world!);console.log(Hello world!);return new Promise((resolve, reject) {// 第二次发生网络请求的代码setTimeout(() {resolve()}, 1000)}).then(() {// 第二次拿到结果后的处理代码console.log(Hello vuejs!);console.log(Hello vuejs!);return new Promise((resolve, reject) {// 第三次发生网络请求的代码setTimeout(() {resolve()}, 1000)}).then(() {// 第三次拿到结果后的处理代码console.log(Hello promise!);console.log(Hello promise!);})})})
/script
/body
/html!DOCTYPE html
html langen
headmeta charsetUTF-8titleTitle/title
/head
bodyscript// 网络请求 aaa - 处理代码10行代码// 处理aaa111 - 处理代码10行代码// 处理aaa111222 - 处理代码10行代码// new Promise((resolve, reject) {})/* new Promise((resolve, reject) {setTimeout(() {resolve(aaa)}, 1000)}).then(res {// 1.自己处理10行代码console.log(res, 第一层的10行处理代码)// 2.对结果进行第一次处理return new Promise((resolve, reject) {resolve(res 111)})}).then(res {console.log(res, 第二层的10处理代码);return new Promise((resolve, reject) {resolve(res 222)})}).then(res {console.log(res, 第三层的10处理代码);})*/// 2.// new Promise((resolve, reject) {// setTimeout(() {// resolve(aaa)// }, 1000)// }).then(res {// // 1.自己处理10行代码// console.log(res,第一层的10行处理代码)//// // 2.对结果进行第一次处理// // return new Promise((resolve, reject) {// // resolve(res 111)// // })// return Promise.resolve(res 111)// }).then(res {// console.log(res, 第二层的10处理代码);//// return Promise.resolve(res 222)//// }).then(res {// console.log(res, 第三层的10处理代码);// })// 链式调用中间某一层出现reject的情况会直接执行最后面的catch()// new Promise((resolve, reject) {// setTimeout(() {// resolve(aaa)// }, 1000)// }).then(res {// // 1.自己处理10行代码// console.log(res, 第一层的10行处理代码)//// // 2.对结果进行第一次处理// // return new Promise((resolve, reject) {// // resolve(res 111)// // })// return Promise.reject(error message)// }).then(res {// console.log(res, 第二层的10处理代码);//// return Promise.resolve(res 222)//// }).then(res {// console.log(res, 第三层的10处理代码);// }).catch(err {// console.log(err);// })// thrownew Promise((resolve, reject) {setTimeout(() {resolve(aaa)}, 1000)}).then(res {// 1.自己处理10行代码console.log(res, 第一层的10行处理代码)// 2.对结果进行第一次处理// return new Promise((resolve, reject) {// resolve(res 111)// })throw error message}).then(res {console.log(res, 第二层的10处理代码);return Promise.resolve(res 222)}).then(res {console.log(res, 第三层的10处理代码);}).catch(err {console.log(err);})// 3.省略掉Promise.resolve// new Promise((resolve, reject) {// setTimeout(() {// resolve(aaa)// }, 1000)// }).then(res {// // 1.自己处理10行代码// console.log(res, 第一层的10行处理代码)//// return res 111// }).then(res {// console.log(res, 第二层的10处理代码);//// return res 222//// }).then(res {// console.log(res, 第三层的10处理代码);// })/script
/body
/html4.1 链式调用 我们在看Promise的流程图时发现无论是then还是catch都可以返回一个Promise对象。 所以我们的代码其实是可以进行链式调用的 这里我们直接通过Promise包装了一下新的数据将Promise对象返回了
Promise.resovle()将数据包装成Promise对象并且在内部回调resolve()函数Promise.reject()将数据包装成Promise对象并且在内部回调reject()函数
4.2 链式调用简写
简化版代码 如果我们希望数据直接包装成Promise.resolve那么在then中可以直接返回数据
注意下面的代码中我将return Promise.resovle(data)改成了return data结果依然是一样的 4.3 all方法的使用
当需要多个网络请求都成功后才能进行下一步操作时可以使用Promise的all方法
!DOCTYPE html
html langen
headmeta charsetUTF-8titleTitle/title
/head
bodyscript// Promise.all([// new Promise((resolve, reject) {// $ajax({// url: url1,// success: function (data) {// resolve(data)// }// })// }),//// new Promise((resolve, reject) {// $ajax({// url: url2,// success: function (data) {// resolve(data)// }// })// })Promise.all([new Promise((resolve, reject) {setTimeout(() {resolve(result1)},2000)}),new Promise((resolve, reject) {setTimeout(() {resolve(result2)},1000)})]).then(results {console.log(results);})/script
/body
/html