1. 程式人生 > >05——wepy框架中的一些細節

05——wepy框架中的一些細節

失敗 while || 檢查 ces LV rand apply eject

1.wepy組件的編譯

wepy中使用一個組件時候,需要先引用(import)。再在需要使用該組件的頁面(或組件)中聲明。例如:

import Counter from ‘/path/to/Counter‘;

components = {   counter1: Counter, counter2: Counter
}

引入一個組件要出現在多處分別使用時,需要為組件分配不同的id,此處分別為counter1,counter2。

如果Counter組件模板

<view>{{counter}}</view>

則編譯後的counter1內容在其引用的頁面中的樣子為:

<view>{{$counter1$counter}}</view>

編譯後的counter2內容為

<view>{{$counter2$counter}}</view>

2.wepy組件中的setData

wepy通過在函數運行周期結束時候,進行臟值檢查,以便使用者可以不用手動setData更新視圖。

但是在組件中,由於組件被編譯成了$prefix$value的形式,即組件中定義的data,無法直接通過this.setData({key:value})形式去更新。

如果需要手動調用this.setData({key: value});需要這樣使用-> this.setData({this.$prefix+key: value});

用上面的Counter組件為例:

  export default class Counter extends wepy.component {
    data = {
      counter: 1     
    }
  
onload() {
// 正確
    this.setData({this.prefix+‘counter‘: 2});
    this.data = 2; //setData 完要記得更新counter中的值。
    // 錯誤
    this.setData({counter: 2});
}
}

應用場景:臟值檢查時候由於值未更新,所以不會自動觸發setData去更新(臟值檢查會在合適時觸發setData)。有時候需要特殊的效果

比如focus文本框,此時文本框已經失去了焦點,但是控制文本框焦點的變量值仍為true。此時想要讓文本框再次獲得焦點,setData一下。

3.wepy對於wx.xxx一系列的promise化

 1 // 原生代碼:
 2 wx.request({
 3     url: ‘xxx‘,
 4     success: function (data) {
 5         console.log(data);
 6     }
 7 });
 8 
 9 // WePY 使用方式
10 wepy.request(‘xxxx‘).then((d) => console.log(d));

原生代碼中需要將成功回調作為參數傳入request,wepy中可以通過promise的用法使用。

其中核心的代碼如下:

技術分享圖片

其中obj為傳入函數的參數。

翻譯一下這段代碼就是:

var wx = {
  getStorage: function(config) {
    // 如果異步事情搞定:
    if(ok) {
      config.success(res);
    } else {
      config.error({err:‘錯誤‘});
    }
  }
}

//使用
wx.getStorage({
  success: (res)=> {},
  error: (err) => {}
});

// promisify
Object.defineProperties(wx, ‘getStorage‘, {
  get() {
    // get函數,則返回函數
    // obj為傳入函數的參數
    return (obj) => {
      obj = obj || {};
      var p = new Promise((okFn, errFn) => {
        const oldHandler = {};
        oldHandler[‘success‘] = obj.success;
        oldHandler[‘failed‘] = obj.failed;
        // 成功的話,resolve這個promise。
        obj.success = (res) => {
          okFn(res);
        }
        // 失敗的話reject這個promise。
        obj.error = (err) => {
          errFn(err);
        };
        // 調用這個函數
        wx.getStorage(obj);
      });
      // 返回這個promise
      return p;
    }
  }
})

4.wepy對請求隊列的優化

原生的小程序對並發的請求有最大個數限制是10個。也就是說一次發送11個請求就會報錯。

wepy對其進行了優化,其核心代碼如下:

import native from ‘./native‘;

let RequestMQ = {
    map: {},
    mq: [],
    running: [],
    MAX_REQUEST: 5,
    push (param) {
        param.t = +new Date();
        while ((this.mq.indexOf(param.t) > -1 || this.running.indexOf(param.t) > -1)) {
            param.t += Math.random() * 10 >> 0;
        }
        this.mq.push(param.t);
        this.map[param.t] = param;
    },
    next () {
        let me = this;

        if (this.mq.length === 0)
            return;

        if (this.running.length < this.MAX_REQUEST - 1) {
            let newone = this.mq.shift();
                let obj = this.map[newone];
                let oldComplete = obj.complete;
                obj.complete = (...args) => {
                    me.running.splice(me.running.indexOf(obj.t), 1);
                    delete me.map[obj.t];
                    oldComplete && oldComplete.apply(obj, args);
                    me.next();
                }
                this.running.push(obj.t);
                return wx.request(obj);
        }
    },
    request (obj) {

        obj = obj || {};
        obj = (typeof(obj) === ‘string‘) ? {url: obj} : obj;


        this.push(obj);

        return this.next();
    }
};

核心思想為,維護一個等待隊列和一個執行中隊列。如果有請求過來,先放到等待隊列,然後判斷執行隊列中任務數是否達到最大,未達到最大則從等待隊列取出任務放到執行隊列執行。一旦執行隊列有任務執行完成。則進行新一輪的檢查\執行。

05——wepy框架中的一些細節