將先後端交互同步化(本篇封裝了一下微信小程序的請求)

今天本身寫小程序的時候,近乎被異步搞到崩潰,不停地嵌套回調(我知道 await 和 promise,可是我嫌promise寫起來跟裹腳布似的,而await我怕有兼容性問題也歷來沒有試過)
言歸正傳,將小程序的異步調用變爲同步(如下教程適用於全部異步,只是給小程序作了一下封裝)。
原理:增長事件隊列,採用事件回調來完成同步化es6

如下代碼複製粘貼到控制檯便可測試效果;
這裏直接寫es6代碼了,先寫個定時器版本的方便測試與理解
先寫個無註釋版本的,方便直接看代碼json

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

可是同步只是異步迫不得已的選擇,因此不能所有否決掉異步promise

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

而後加入小程序的接口調用方法app

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 同時 發起請求
相關文章
相關標籤/搜索