无码日韩精品无码国产_一级做a爰片久久毛片潮喷_国产欧美国日产_久久9热re这里只有国产中文精品6_每天将为您更新成人影视在线看免费观看

Menu
小程序資訊
小程序資訊
微信小程序使用Promise實踐
時間:2016-10-17 16:06:00
官方小例子代碼
getUserInfo:function(cb){
    var that = this
    if(this.globalData.userInfo){
      typeof cb == "function" && cb(this.globalData.userInfo)
    }else{
      //調用登錄接口
      wx.login({
        success: function () {
          wx.getUserInfo({
            success: function (res) {
              that.globalData.userInfo = res.userInfo
              typeof cb == "function" && cb(that.globalData.userInfo)
            }
          })
        }
      })
    }
  },

昨天研究了一下微信小程序的例子,看見了熟悉cb了。我們好不容易從cb走向了Promise,如果開發(fā)小程序要回到cb中,這是我不能接受的,搞得我昨晚一晚上沒有睡好,今年早一大早就到公司想辦法解決問題。

解決思路 1、直接使用Promise,我試了一下,是可行的,但這受限于運行程序的瀏覽器。不能保證所有瀏覽器都支持Promise。 2、使用第三方庫,bluebird,Q,Defrered等,這樣可以不依賴瀏覽器實現(xiàn)。 說做就做,我最熟悉的是bluebird,于是先就在工程文件夾下執(zhí)行

npm init
npm i bluebird --save

得到項目結構如下圖

在App.js中寫入

var Promise = require("node_modules/node_modules/js/browser/bluebird.js");

通過調試發(fā)現(xiàn)Promise為undfine,解決問題失敗! 深入分析 難道真如網上所說不能加載第三方JS?我覺得應該不可能,如果不能使用第三方程序,什么都靠自己寫,累都累死。忽然想到一段代碼

logs.js
var util = require('../../utils/util.js')

util.js
module.exports = {
  formatTime: formatTime
}

如果能在logs.js中引入util.js,就一定能引第三方包,只是我沒有搞清楚這個加載機制??瓷厦娴拇a好像是CMD。我想來想去,最終在瀏覽器發(fā)現(xiàn)了這個。

define("utils/util.js", function(require, module){var window={Math:Math}/*兼容babel*/,location,document,navigator,self,localStorage,history,Caches;

module.exports = {
  formatTime: formatTime
}

})

這是瀏覽加載后的代碼,通過代碼分析,總結出如下經驗: 1、原來小程序是自己定義了一套加載機制,不是CMD也不是AMD,到有點與NG相同。 2、小程序會為每個js文件加一個包頭,每個包中都增加一個window對象,所以在小程序中,window對象是一個局部變量。 3、document對象不一定有值 4、require是一個函數(shù),module是一個對象這點與CMD一至 再次嘗試 要在小程序中使用第三方包,就必須修改加載頭。當我打開個bluebird源碼時,立馬就懵逼了,看不懂。所以就選擇了Q,這個簡單些,先看沒有修改之樣的。

(function (definition) {
    "use strict";

    // This file will function properly as a <script> tag, or a module
    // using CommonJS and NodeJS or RequireJS module formats.  In
    // Common/Node/RequireJS, the module exports the Q API and when
    // executed as a simple <script>, it creates a Q global instead.

    // Montage Require
    if (typeof bootstrap === "function") {
        bootstrap("promise", definition);

    // CommonJS
    } else if (typeof exports === "object" && typeof module === "object") {
        module.exports = definition();

    // RequireJS
    } else if (typeof define === "function" && define.amd) {
        define(definition);

    // SES (Secure EcmaScript)
    } else if (typeof ses !== "undefined") {
        if (!ses.ok()) {
            return;
        } else {
            ses.makeQ = definition;
        }

    // <script>
    } else if (typeof window !== "undefined" || typeof self !== "undefined") {
        // Prefer window over self for add-on scripts. Use self for
        // non-windowed contexts.
        var global = typeof window !== "undefined" ? window : self;

        // Get the `window` object, save the previous Q global
        // and initialize Q as a global.
        var previousQ = global.Q;
        global.Q = definition();

        // Add a noConflict function so Q can be removed from the
        // global namespace.
        global.Q.noConflict = function () {
            global.Q = previousQ;
            return this;
        };

    } else {
        throw new Error("This environment was not anticipated by Q. Please file a bug.");
    }

})(function () {
"use strict";

這段代碼,我立馬就看懂了,這就是一個標準的閉包,definition是定義函數(shù),Q一共適配了CommonJS,RequireJS加載,但可惜能過調試,進入了<script>這個分支,原因很簡單,有window對象。但此window不是彼window,所以加載失敗。

想明白了就好改了,改后代碼如下:

(function (definition) {
    "use strict";
    module.exports = definition();
})(function () {
"use strict";

需要注意的是definition后面一定要帶(),表示執(zhí)行這個函數(shù),我一開始沒有執(zhí)行,結果使用時沒有得到Q對象。原因是definition函數(shù)返回Q對象,大家看最一行代碼。 使用Q改寫獲取用戶 Q的使用很簡單,主要改了這樣幾處地方

//app.js
var Q = require("utils/q.js");
App({
  onLaunch: function () {
    //調用API從本地緩存中獲取數(shù)據(jù)
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)
  },
  globalData:{
    userInfo:null
  },
  login : function() {
    var def = Q.defer();
    wx.login({
      success : function() {
        def.resolve();
      }
    });
    return def.promise;
  },
  getUserInfo : function() {
    var that = this;
    var def = Q.defer();
    
    if( this.globalData.userInfo ) {
      def.resolve(this.globalData.userInfo);
    } else {
      this.login().then(function(){
        wx.getUserInfo({
          success : function( res ) {
            that.globalData.userInfo = res.userInfo;
            def.resolve(res.userInfo);
          }
        });
      });
    }

    return def.promise;
  }
})
//index.js
//獲取應用實例
var app = getApp()
Page({
  data: {
    motto: 'Hello World',
    userInfo: {}
  },
  //事件處理函數(shù)
  bindViewTap: function() {
    wx.navigateTo({
      url: '../logs/logs'
    })
  },
  onLoad: function () {
    console.log('onLoad')
    var that = this
    //調用應用實例的方法獲取全局數(shù)據(jù)
    app.getUserInfo().then(function(userInfo){
      that.setData({
        userInfo:userInfo
      })
    });
    console.log(window.document);
  }
})

總結 1、不要先入為主,網上的東西不能不信,也不能盡信,盡量去自己嘗試。 2、X訊自己造了一個封閉的環(huán)境,開放?封閉?這個東西好壞得時間來驗證。 3、得理解包加載機制,基礎的東西最重要。

咨詢
微信掃碼咨詢
電話咨詢
400-888-9358