promise ES6新增的一个重要属性
promise是解决异步编程的一种解决方案 主要简化网络请求 避免回调地狱
同步指的是一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。
异步指的是每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。
首先js是单线程的语言,即同一时间只能做做一件事。那Js如何实现异步的,异步和单线程不是自相矛盾吗?其实,单线程和异步确实不能同时成为一个语言的特性。js选择了成为单线程的语言,所以它本身不可能是异步的,但js的宿主环境(比如浏览器,Node)是多线程的,宿主环境通过某种方式(事件驱动,下文会讲)使得js具备了异步的属性
new > 构造函数(1.保存了一些状态信息 2.执行传入的函数)
创建新空间 存入对象 this指向这个对象 执行构造函数代码 给对象数据 最后 return 出来
在执行传入的回调函数时
会传入两个参数 resolve reject 本身又是函数 then 执行下一步 catch捕获错误
一般情况下 有异步操作时。会使用Promise 对这个异步操作进行封装
它是链式结构 比嵌套明了
- //1.使用setTimeout 实现异步操作
- setTimeout(()=>{
- console.log('hello world');
- },1000)
-
- new Promise((resolve,reject) => {
- //第一次网络请求的代码
- setTimeout(()=>{
- resolve()
- },1000)
- }).then(()=>{
- //返回数据处理第一次的代码
- console.log('第一次延迟打印1');
-
- return new Promise((resolve, reject)=>{
- //第二次网络请求的代码
- setTimeout(()=>{
- resolve()
- },1000)
- }).then(()=>{
- //返回数据处理第二次的代码
- console.log('第二次延迟打印2');
- console.log('第二次延迟打印2');
-
- return new Promise((resolve, reject) => {
- //第三次网络请求的代码
- setTimeout(()=>{
- resolve()
- },1000)
- }).then(()=>{
- //返回数据处理第三次的代码
- console.log('第三次延迟打印3');
- console.log('第三次延迟打印3');
- console.log('第三次延迟打印3');
- })
- })
- })
-
- //什么情况下会用到Promise?
- //一般情况下 有异步操作时。会使用Promise 对这个异步操作进行封装
- // new > 构造函数(1.保存了一些状态信息 2.执行传入的函数)
- //在执行传入的回调函数时,会传入两个参数 resolve reject 本身又是函数
-
- new Promise((resolve, reject)=>{
- setTimeout(()=>{
- // 手动调用 只执行一次
- //成功的时候
- resolve('最后的数据')
- //失败的时候
- reject('错误信息')
-
- },4000)
- }).then((data)=>{
- console.log(data);
- }).catch((err)=>{
- console.log(err);
- })
pending 等待状态 比如正在进行网络请求,或者定时器没有到时间
fulfill: 满足状态,当我们主动回调了resolve时,就处于该状态,并且会回调 then()
reject: 拒绝状态,当我们主动回调了 reject 时, 就处于该状态,并且会回调catch()
new Promise((resolve, reject)=>{
setTimeout(()=>{
// 手动调用 只执行一次
//成功的时候
resolve('最后的数据')
//失败的时候
reject('错误信息')},4000)
}).then( data =>{
console.log(data);
}, err => {console.log(err);
})
可以把网络请求的代码和 数据请求过来进行相关操作的代码 分离开来 灵活抛出 resolve reject
对应执行 then catch
- new Promise((resolve, reject)=>{
- setTimeout(()=>{
- resolve('aaa')
- },1000)
- }).then(skt=>{
- console.log(skt,'第一次处理的代码');
- return new Promise((resolve,reject) => {
- //resolve(skt+'bbb')
- reject()
- }).then(skt=>{
- console.log(skt,'第二次处理的代码');
- return new Promise(resolve => {
- resolve(skt+'ccc')
- })
- }).then(skt=>{
- console.log(skt,'第三次处理的代码');
- })
- }).catch(()=>{
- console.log('错误终止');
- }).catch(()=>{
- console.log('错误终止');
- })
-
- //简化 top1 new Promise((resolve => resolve(结果)) 简写
- new Promise((resolve, reject)=>{
- setTimeout(()=>{
- resolve('111')
- },2000)
- }).then(skt=>{
- console.log(skt,'第四次处理的代码');
- return Promise.resolve(skt+'222')
- }).then(skt=>{
- console.log(skt,'第五次处理的代码');
- return Promise.reject()
- }).then(skt=>{
- console.log(skt,'第六次处理的代码');
- }).catch(()=>{
- console.log('错误终止');
- })
-
- //再简化 省略Promise.resolve
- new Promise((resolve, reject)=>{
- setTimeout(()=>{
- resolve('123')
- },3000)
- }).then(skt=>{
- console.log(skt,'第七次处理的代码');
- return (skt+'456')
- }).then(skt=>{
- console.log(skt,'第八次处理的代码');
- //return (skt+'789')
- throw '错误终止'
- }).then(skt=>{
- console.log(skt,'第九次处理的代码');
- }).catch(()=>{
- console.log('错误终止');
- })
传入可迭代对象(类数组)为不同的Promise 它会在所有Promise结果为resolve时 执行最终的then,如果有一项为reject 那么就执行 catch
- Promise.all([
- new Promise((resolve, reject)=>{
- setTimeout(()=>{
- resolve([
- 1,2,3,4,5,{name:webkitURL}
- ])
- },2000)
- }),
-
- new Promise((resolve, reject)=>{
- setTimeout(()=>{
- //reject()
- resolve([14,24])
- },2000)
- }),
-
- ]).then(arr=>{
- console.log(arr[0]);
- console.log(arr[1]);
- }).catch(err => {
- console.log('项目中有失败的');
- })