将前后端交互同步化(本篇封装了一下微信小程序的请求)
今天自己写小程序的时候,近乎被异步搞到崩溃,不停地嵌套回调(我知道 await 和 promise,但是我嫌promise写起来跟裹脚布似的,而await我怕有兼容性问题也从来没有试过)
言归正传,将小程序的异步调用变为同步(以下教程适用于所有异步,只是给小程序做了一下封装)。
原理:增加事件队列,采用事件回调来完成同步化
以下代码复制粘贴到控制台即可测试效果;
这里直接写es6代码了,先写个定时器版本的方便测试与理解
先写个无注释版本的,方便直接看代码
class Async{ constructor() { this.list = []; this.sock = false; } request(obj) { setTimeout(() => { console.log(obj); this.sock = false; if(this.list[0]) this.do(this.list.shift()); }, 1000) } do(requestObj, sync) { if(!sync) { return this.request(requestObj); } if(this.sock) { this.list.push(requestObj); }else { this.sock = true; this.request(requestObj); } } }
-----------以下为注释版本-----------
class Async{ constructor() { this.list = []; // 定义 执行队列 this.sock = false; // 判断是否有任务正在执行 } request(obj) { setTimeout(() => { console.log(obj); this.sock = false; // 重置为没有任务正在执行 if(this.list[0]) // 如果队列中还有任务,执行下一个任务 this.do(this.list.shift()); }, 1000) // 模拟一个异步,一秒后执行任务,执行完成后执行下一个异步任务 } do(requestObj) { if(this.sock) // 如果有任务在执行 this.list.push(requestObj); // 将当前任务其增加到任务队列 else { this.sock = true; // 否则开始执行当前任务并设定'有任务在执行' this.request(requestObj); } } } var x = new Async(); x.do({url: 1}); // 一秒后打印 url: 1 x.do({url: 2}); // 两秒后打印 url: 2
但是同步只是异步无可奈何的选择,所以不能全部否决掉异步
class Async{ constructor() { this.list = []; // 定义 执行队列 this.sock = false; // 判断是否有任务正在执行 } request(obj) { setTimeout(() => { console.log(obj); this.sock = false; // 重置为没有任务正在执行 if(this.list[0]) // 如果队列中还有任务,执行下一个任务 this.do(this.list.shift()); }, 1000) // 模拟一个异步,一秒后执行任务,执行完成后执行下一个异步任务 } do(requestObj, sync) { if(!sync) // 判断是否需要同步,如果需要再加入到队列,不然直接执行 return this.request(requestObj); if(this.sock) // 如果有任务在执行 this.list.push(requestObj); // 将当前任务其增加到任务队列 else { this.sock = true; // 否则开始执行当前任务并设定'有任务在执行' this.request(requestObj); } } } var x = new Async(); x.do({url: 1}, true); // 一秒后打印 url: 1 x.do({url: 2}, true); // 两秒后打印 url: 2 x.do({url: 3}); // 一秒后打印 url: 3
然后加入小程序的接口调用方法
class AsyncRequest{ constructor() { this.list = []; // 定义 执行队列 this.sock = false; // 判断是否有任务正在执行 } request(obj) { wx.request({ url: obj.url, data: obj.data, header: { 'content-type': 'application/json' }, success: res => { obj.cb(res); if(this.list[0]) this.do(this.list.shift()); } }) } do(requestObj, sync) { if(!sync) // 判断是否需要同步,如果需要再加入到队列,不然直接执行 return this.request(requestObj); if(this.sock) // 如果有任务在执行 this.list.push(requestObj); // 将当前任务其增加到任务队列 else { this.sock = true; // 否则开始执行当前任务并设定'有任务在执行' this.request(requestObj); } } } var x = new AsyncRequest(); x.do({url: 1, data: {test: 1}, cb: ()=> {}}, true); // 先请求接口1 x.do({url: 2}, true); // 1 请求完成后请求接口2 x.do({url: 3}); // 和 1 同时 发起请求
相关推荐
kgshuo 2020-09-25
Tomato 2020-09-10
taiyangyu 2020-09-10
CodeAndroid 2020-09-10
small 2020-07-29
sucheng 2020-07-26
zuoliangzhu 2020-07-20
CodeAndroid 2020-07-14
xiaoxubbs 2020-07-04
sucheng 2020-06-25
kgshuo 2020-06-14
意外金喜 2020-06-14
zuoliangzhu 2020-06-14
tianping 2020-06-14
hgzhang 2020-06-14
killgod 2020-06-14
戴翔的技术 2020-06-14
郴州小程序 2020-06-13