1.使用Promise的目的
使用Promise 网络请求部分+页面其他主程序能够各自互不干扰进行。
1.1 异步和同步
js代码实际上是单线程程序,代码是一行一行的执行。
但是如果在同步程序中发送了网络请求,如果超时了,而下一步大代码依赖于网络请求,那么整个网页会失去响应。
异步执行的过程不再与原先的序列有顺序关系,特别是发送网络请求,网路请求无论多长时间,程序不会在此等待,直接走下面的代码。等异步的请求有响应之后,自己完成回调后续的操作,程序之间不会互相影响。
1.1.1同步
第一个接口获取到的数据是第二个接口请求的参数,第二个接口获取到的数据是第三个接口请求的参数...这样需要第一个接口的请求结束,才能继续第二而后进行第三个。
第二个接口请求和第三个接口的请求都依赖于前一个接口的请求完成。
1.1.2异步
请求可以分开各自进行,更加高效的完成
1.2回调地狱
异步调取获取到结果之后,为下一个异步函数提供数据,所以会一层层地回调内部嵌套回调,套娃式地导致代码维护愈来愈复杂。
2.初始版0.0回调地狱
onLoad(options){ this.getData() }, getData(){ //获取分类列表id uni.request({ url:"https://ku.qingnian8.com/dataApi/news/navlist.php", success:res=>{ let id=res.data[0].id // 根据分类id获取该分类下的所有文章 uni.request({ url:"https://ku.qingnian8.com/dataApi/news/newslist.php", data:{ cid:id }, success:res2=>{ //获取到一篇文章的id,根据文章id找到该文章下的评论 let id=res2.data[0].id; uni.request({ url:"https://ku.qingnian8.com/dataApi/news/comment.php", data:{ aid:id }, success:res3=>{ //找到该文章下所有的评论 console.log(res3) } }) } }) } }) }
3.1.0版本 简单封装,但本质还是回调地狱
onLoad(options){ // 回调地狱 套娃1.0 this.getNav(res => { let id = res.data[1].id // console.log(res) this.getnewsList(id, res => { let id = res.data[1].id console.log(id) this.getcomList(id,res=>{ console.log("success") console.log(res) }) }) }) }, // 回调地狱 套娃1.0 getNav(callback) { wx.request({ url: 'https://ku.qingnian8.com/dataApi/news/navlist.php', success: res => { callback(res) } }) }, getList(id, callback) { wx.request({ url: 'https://ku.qingnian8.com/dataApi/news/newslist.php', data: { cid: id }, success: res => { callback(res) } }) }, getcomList(id,callback){ wx.request({ url:'https://ku.qingnian8.com/dataApi/news/comment.php', data:{ aid:id }, success:res=>{ callback(res) } }) },
4.2.0版本Promise链式异步
onLoad(options){ // 异步 promise链式2.0版本 this.getNavList().then(res=>{ let id=res.data[0].id; return this.getNewsList(id); }).then(res=>{ // console.log(res) let id=res.data[0].id return this.getComList(id); }).then(res=>{ console.log(res) }).catch(err=>{ console.log(err) }) }, // 异步2.0 request:ok 只是代表发送请求成功,但是主要看data数据以及statusCode,404访问出错,200或者其他数字访问成功 getNavList(){ return new Promise((resolve,reject)=>{ wx.request({ url: 'https://ku.qingnian8.com/dataApi/news/navlist.php', success:res=>{ resolve(res) }, fail:err=>{ reject(err) } }) }) }, getNewsList(id){ return new Promise((resolve,reject)=>{ wx.request({ url: 'https://ku.qingnian8.com/dataApi/news/newslist.php', data:{ cid:id }, success:res=>{ resolve(res) }, fail:err=>{ reject(err) } }) }) }, getComList(id){ return new Promise((resolve,reject)=>{ wx.request({ url: 'https://ku.qingnian8.com/dataApi/news/newslist.php', data:{ cid:id }, success:res=>{ resolve(res) }, fail:err=>{ reject(err) } }) }) }, getnavList(){ let p=new Promise((resolve,reject)=>{ wx.request({ url: 'https://ku.qingnian8.com/dataApi/news/navlist.php', success:res=>{ resolve(res) }, fail:err=>{ reject(err) } }) }) p.then(res=>{ console.log(res) }).catch(err=>{ // reject(err) console.log(err) }) },
5.3.0版本Promise
await / async ES7的新规范,异步处理同步化 ,
在前面加入await,等这一步的异步方法执行成功之后,将返回的值赋值给res变量,然后再执行下一行代码,将之前的异步编程改变为同步编程
即:异步处理,同步化
async onLoad(options){ //前提是promise对象 才能使用await ES7使用异步请求,异步处理同步化 let id,res; res=await this.getNavList(); id=res.data[0].id; console.log(res) res=await this.getNewsList(id); id=res.data[0].id; console.log(res) res=await this.getComList(id); console.log(res) let p1=this.getNavList(); let p2=this.getNewsList(51); let p3=this.getComList(251); Promise.all([p1,p2,p3]).then(res=>{ console.log(res) }) }, //这部分函数和2.0版本内容一样 getNavList(){ return new Promise((resolve,reject)=>{ wx.request({ url: 'https://ku.qingnian8.com/dataApi/news/navlist.php', success:res=>{ resolve(res) }, fail:err=>{ reject(err) } }) }) }, getNewsList(id){ return new Promise((resolve,reject)=>{ wx.request({ url: 'https://ku.qingnian8.com/dataApi/news/newslist.php', data:{ cid:id }, success:res=>{ resolve(res) }, fail:err=>{ reject(err) } }) }) }, getComList(id){ return new Promise((resolve,reject)=>{ wx.request({ url: 'https://ku.qingnian8.com/dataApi/news/newslist.php', data:{ cid:id }, success:res=>{ resolve(res) }, fail:err=>{ reject(err) } }) }) }, getnavList(){ let p=new Promise((resolve,reject)=>{ wx.request({ url: 'https://ku.qingnian8.com/dataApi/news/navlist.php', success:res=>{ resolve(res) }, fail:err=>{ reject(err) } }) }) p.then(res=>{ console.log(res) }).catch(err=>{ // reject(err) console.log(err) }) },
6.什么是Promise?
promise是解决异步的方法,本质上是一个构造函数,可以用它实例化一个对象。对象身上有resolve、reject、all,原型上有then、catch方法。promise对象有三种状态:pending(初识状态/进行中)、resolved或fulfilled(成功)、rejected(失败)
-
pending。它的意思是 "待定的,将发生的",相当于是一个初始状态。创建Promise对象时,且没有调用resolve或者是reject方法,相当于是初始状态。这个初始状态会随着你调用resolve,或者是reject函数而切换到另一种状态。
-
resolved。表示解决了,就是说这个承诺实现了。 要实现从pending到resolved的转变,需要在 创建Promise对象时,在函数体中调用了resolve方法
-
rejected。拒绝,失败。表示这个承诺没有做到,失败了。要实现从pending到rejected的转换,只需要在创建Promise对象时,调用reject函数。
7.总结:
如果涉及到网络请求没有依赖关系的话,异步请求是效率最高的,但是下一个的方法依赖于上一个网络请求的结果,那么久必须使用await命令,将异步结果等待返回之后再执行后面的代码
主要出处是b站up主咸虾米_,本文为自我总结归纳整理
作者:咸虾米_ ES6 Promise的用法,async/await异步处理同步化 - 哔哩哔哩 出处:bilibili