用戶
 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

掃一掃,登錄網站

小程序社區 首頁 教程 查看內容

小程序摸爬滾打之路

Rolan 2020-1-10 00:12

上面這張圖相信接觸過小程序的開發者多多少少都有看到過,小程序的渲染層和邏輯層分別由 2 個線程管理:視圖層的界面使用了 WebView 進行渲染,邏輯層采用 JsCore 線程運行 JS腳本。那么為什么要這樣設計呢,為了管 ...

上面這張圖相信接觸過小程序的開發者多多少少都有看到過,小程序的渲染層和邏輯層分別由 2 個線程管理:視圖層的界面使用了 WebView 進行渲染,邏輯層采用 JsCore 線程運行 JS腳本。

那么為什么要這樣設計呢,為了管控和安全,我們需要阻止開發者使用一些,例如瀏覽器的window對象,跳轉頁面、操作DOM、動態執行腳本的開放性接口。

我們可以使用客戶端系統的 JavaScript 引擎,iOS 下的 JavaScriptCore 框架,安卓下騰訊 x5 內核提供的 JsCore 環境。

這個沙箱環境只提供純 JavaScript 的解釋執行環境,沒有任何瀏覽器相關接口。

2.雙線程之間的通信

既然小程序的模型是雙線程模型,那么是如何實現雙線程之間的通信呢,由上圖可以看出,邏輯層和視圖層是通過Native層來進行轉發的,這也就是說,我們可以把 DOM 的更新通過簡單的數據通信來實現,類似于虛擬DOM的實現,用JS對象模擬DOM樹,然后進行diff,然后把差異在視圖層進行渲染,這一系列在Native之間的轉化則由小程序的基礎庫來完成。

3.組件系統--Exparser框架

Exparser是微信小程序的組件組織框架,內置在小程序基礎庫中,為小程序的各種組件提供基礎的支持。小程序內的所有組件,包括內置組件和自定義組件,都由Exparser組織管理。

  • DOM模型:模型上與WebComponents的ShadowDOM高度相似,但不依賴瀏覽器的原生支持,也沒有其他依賴庫;實現時,還針對性地增加了其他API以支持小程序組件編程。
  • 可在純JS環境中運行:這意味著邏輯層也具有一定的組件樹組織能力。
  • 高效輕量:性能表現好,在組件實例極多的環境下表現尤其優異,同時代碼尺寸也較小。

當前Web Component已經支持局部作用域、slot插槽等等現有框架所提供的組件化方法,學習Web Component也是我接下來自己學習的目標之一 Orz 。

4.setData干了些什么

小程序的視圖層目前使用 WebView 作為渲染載體,而邏輯層是由獨立的 JavascriptCore 作為運行環境。在架構上,WebView 和 JavascriptCore 都是獨立的模塊,并不具備數據直接共享的通道。當前,視圖層和邏輯層的數據傳輸,實際上通過兩邊提供的 evaluateJavascript 所實現。即用戶傳輸的數據,需要將其轉換為字符串形式傳遞,同時把轉換后的數據內容拼接成一份 JS 腳本,再通過執行 JS 腳本的形式傳遞到兩邊獨立環境。

而 evaluateJavascript 的執行會受很多方面的影響,數據到達視圖層并不是實時的。

5.運行機制

小程序啟動會有兩種情況,一種是「冷啟動」,一種是「熱啟動」。假如用戶已經打開過某小程序,然后在一定時間內再次打開該小程序,此時無需重新啟動,只需將后臺狀態的小程序切換到前臺,這個過程就是熱啟動;冷啟動指的是用戶首次打開或小程序被微信主動銷毀后再次打開的情況,此時小程序需要重新加載啟動。

小程序開發日常問題

1.wx.request()的promise化

小程序框架自帶的網絡請求和Ajax請求非常相似都是異步請求,請求參數中需要送入url、method、data、header等參數,還要設置success成功的回調函數和fail失敗的回調函數,如下圖所示

通過回調函數處理就很容易造成回調地獄,所以Promise化還是很有必要的

class request {
  constructor() {
    this._baseUrl = 'https://xxx.com/api';
    this._token = wx.getStorageSync('token');
    this._header = {}
  }

  /**
   * GET類型的網絡請求
   */
  getRequest(url, data, header = this._header) {
    return this.requestAll(url, data, header, 'GET')
  }

  /**
   * DELETE類型的網絡請求
   */
  deleteRequest(url, data, header = this._header) {
    return this.requestAll(url, data, header, 'DELETE')
  }

  /**
   * PUT類型的網絡請求
   */
  putRequest(url, data, header = this._header) {
    return this.requestAll(url, data, header, 'PUT')
  }

  /**
   * POST類型的網絡請求
   */
  postRequest(url, data, header = this._header) {
    return this.requestAll(url, data, header, 'POST')
  }
  
  requestAll(url, data, header, method) {
    return new Promise((resolve, reject) => {
      wx.request({
        url: this._baseUrl + url,
        data: data,
        header: header,
        method: method,
        success: (res => {
          if (res.statusCode === 200) {
            resolve(res)
          } else {
            //其它錯誤,提示用戶錯誤信息
            reject(res)
          }
        }),
        fail: (res => {
          reject(res)
        })
      })
    })
  }
}

export default request
復制代碼

2.小程序的WXS

在小程序的日常開發中大家肯定會遇到需要對數據進行過濾轉義的場景,而微信小程序沒有像Vue一樣的filter過濾器功能,大多數人會在渲染之前對數據進行一次清洗,而WXS就是為了解決這一痛點

什么是WXS

  • 是小程序出的一套腳本語言,用于 wxml 模板文件中,在模板文件中可以完成頁面的結構。
  • 不依賴于運行時的基礎庫腳本,可以在所有版本的小程序中運行。
  • WXS 中不能調用 javascript 中定義的函數或者變量,也不能調用小程序提供的 API,他的運行環境和 javascript 是隔離的。
  • 小程序的條件渲染和循環渲染對 WXS 是無效的,就是說如果 WXS 代碼包裹在未渲染的代碼中,只要渲染的 wxml 部分調用了此模塊,此段 WXS 代碼依然會被加載。
  • 由于運行環境的差異,在 ios 設備上小程序的 WXS 會比 javascript 快 2~20 倍,在 android 設備上運行效率無異。
  • 模塊想要暴露自己的私有變量和方法,只能通過 module.exports 實現。 若在模塊中想要引用其他模塊,只能通過 require 實現。
  • 只能使用 var 來定義變量,表現形式和 javascript 一樣,會有變量提升。
  • WXS 模塊只能在定義模塊的 wxml 文件中被訪問到,使用 或 時,WXS 模塊不會被引入到對應的 wxml 文件中。
  • 不能使用 new Date() 應該使用 getDate() 。

WXS最常見的用處可能就是實現一個過濾器,如下所示

<wxs module="filter">
    function getFullPath(url) {
        return "https://shiyuanjieyi.cn" + url
    }
    module.exports.getFullPath = getFullPath
</wxs>
<image src="{{filter.getFullPath(url)}}"></image>
復制代碼
鮮花
鮮花 (1)
雞蛋
雞蛋

剛表態過的朋友 (1 人)

分享至 : QQ空間
收藏
原作者: 我切圖賊快 來自: 掘金
梦幻单人赚钱方法 王中王开奖结果24码 今期看单来发财解单双 近期股票为何下跌 天天乐棋牌app 旺旺大庆麻将下载 广西麻将下载官方 最准码王 股市行情走势图 能够赚钱的网页游戏 资产管理平台