资讯专栏INFORMATION COLUMN

将前后端交互同步化(本篇封装了一下微信小程序的请求)

codecraft / 849人阅读

摘要:今天自己写小程序的时候,近乎被异步搞到崩溃,不停地嵌套回调我知道和,但是我嫌写起来跟裹脚布似的,而我怕有兼容性问题也从来没有试过言归正传,将小程序的异步调用变为同步以下教程适用于所有异步,只是给小程序做了一下封装。

今天自己写小程序的时候,近乎被异步搞到崩溃,不停地嵌套回调(我知道 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 同时 发起请求

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/105637.html

相关文章

  • 面试题总结(js、html、小程序、React、ES6、Vue、算法、全栈热门视频资源)

    摘要:并总结经典面试题集各种算法和插件前端视频源码资源于一身的文档,优化项目,在浏览器端的层面上提升速度,帮助初中级前端工程师快速搭建项目。 本文是关注微信小程序的开发和面试问题,由基础到困难循序渐进,适合面试和开发小程序。并总结vue React html css js 经典面试题 集各种算法和插件、前端视频源码资源于一身的文档,优化项目,在浏览器端的层面上提升速度,帮助初中级前端工程师快...

    pumpkin9 评论0 收藏0
  • 面试题总结(js、html、小程序、React、ES6、Vue、算法、全栈热门视频资源)

    摘要:并总结经典面试题集各种算法和插件前端视频源码资源于一身的文档,优化项目,在浏览器端的层面上提升速度,帮助初中级前端工程师快速搭建项目。 本文是关注微信小程序的开发和面试问题,由基础到困难循序渐进,适合面试和开发小程序。并总结vue React html css js 经典面试题 集各种算法和插件、前端视频源码资源于一身的文档,优化项目,在浏览器端的层面上提升速度,帮助初中级前端工程师快...

    Carson 评论0 收藏0
  • 面试题总结(js、html、小程序、React、ES6、Vue、算法、全栈热门视频资源)

    摘要:并总结经典面试题集各种算法和插件前端视频源码资源于一身的文档,优化项目,在浏览器端的层面上提升速度,帮助初中级前端工程师快速搭建项目。 本文是关注微信小程序的开发和面试问题,由基础到困难循序渐进,适合面试和开发小程序。并总结vue React html css js 经典面试题 集各种算法和插件、前端视频源码资源于一身的文档,优化项目,在浏览器端的层面上提升速度,帮助初中级前端工程师快...

    muzhuyu 评论0 收藏0
  • 面试题总结(js、html、小程序、React、ES6、Vue、算法、全栈热门视频资源)

    摘要:并总结经典面试题集各种算法和插件前端视频源码资源于一身的文档,优化项目,在浏览器端的层面上提升速度,帮助初中级前端工程师快速搭建项目。 本文是关注微信小程序的开发和面试问题,由基础到困难循序渐进,适合面试和开发小程序。并总结vue React html css js 经典面试题 集各种算法和插件、前端视频源码资源于一身的文档,优化项目,在浏览器端的层面上提升速度,帮助初中级前端工程师快...

    li21 评论0 收藏0

发表评论

0条评论

codecraft

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<