官方示例代码getuserinfo :函数(CB) {var那=this if (this。global data . user info){ CB的类型==' function' CB(这个。globaldata.userinfo)} else {//调用登录界面wx . log in({ success : function(){ wx . getuser info({ success 3360 function(RES))}。globaldata。userinfo=res. userinfo类型的cb==' function' CB(即。globaldata。userinfo)} } } } } } } } } } } } },昨天学习了微信小程序的例子,看到对CB比较熟悉。我们最终从cb搬到了Promise,如果我们开发小程序回到cb,我是无法接受的。结果昨晚没睡好,今天一早就去公司想办法解决问题。
解决方案1。我尝试过直接用Promise,可行,但是受限于运行程序的浏览器。不能保证所有浏览器都支持Promise。2.使用第三方库、蓝鸟、q、Defrered等。它可以独立于浏览器实现。就这么做吧,我对青鸟最熟悉,所以先在项目文件夹里执行。
Npm initnpm i bluebird - save获取如下所示的项目结构。
用App.js写
var Promise=require(' node _ modules/node _ modules/js/browser/blue bird . js ');通过调试发现Promise不精细,问题解决失败!深度分析第三方JS不能像网上说的那样加载是真的吗?我认为这是不可能的。如果你不能使用第三方程序,你必须自己写所有的东西,你已经筋疲力尽了。突然想到了一段代码。
Logs.js varutil=require('././utils/util.js’)util . js module . exports={ format tie : format time }如果可以把util . js引入到logs.js中,肯定会引入第三方的包,但是我就是不懂加载机制。看,上面的代码好像是CMD。我想了想,终于在浏览器里找到了这个。
定义(' utils/util.js ',函数(require,module){ var window={ math : path }/*兼容babel */,位置,文档,导航器,self,本地存储,历史记录,缓存;模块。exports={ format time : format time } })这是浏览加载后的代码。通过代码分析,总结出以下经验:1。原来小程序自己定义了一套加载机制,既不是CMD也不是AMD,和ng有些相同。2.小程序会给每个js文件添加一个头,给每个包添加一个窗口对象,所以在小程序中,窗口对象是一个局部变量。3.文档对象不一定有值。4.require是一个函数,module是一个对象。这和CMD一样。一旦您再次尝试在小程序中使用第三方包,您必须修改加载头。当我打开一个蓝鸟源代码时,我立刻被弄糊涂了,无法理解它。所以我选了Q,比较简单。我们先来看看未修改的。
(function(definition){ ' use strict ';//使用CommonJS和NodeJS或RequireJS模块格式,该文件将作为脚本标记或模块//正常工作。在//Common/Node/requires js中,模块导出Q API,当//作为简单脚本执行时,它
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是定义函数,Q一共适配了CommonJS,RequireJS加载,但可惜能过调试,进入了<script>这个分支,原因很简单,有window对象。但此window不是彼window,所以加载失败。
想明白了就好改了,改后代码如下:
(function (definition) { "use strict"; module.exports = definition();})(function () {"use strict";
需要注意的是definition后面一定要带(),表示执行这个函数,我一开始没有执行,结果使用时没有得到Q对象。原因是definition函数返回Q对象,大家看最一行代码。 使用Q改写获取用户 Q的使用很简单,主要改了这样几处地方
//app.jsvar Q = require("utils/q.js");App({ onLaunch: function () { //调用API从本地缓存中获取数据 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: {} }, //事件处理函数 bindViewTap: function() { wx.navigateTo({ url: '../logs/logs' }) }, onLoad: function () { console.log('onLoad') var that = this //调用应用实例的方法获取全局数据 app.getUserInfo().then(function(userInfo){ that.setData({ userInfo:userInfo }) }); console.log(window.document); }})
总结 1、不要先入为主,网上的东西不能不信,也不能尽信,尽量去自己尝试。 2、X讯自己造了一个封闭的环境,开放?封闭?这个东西好坏得时间来验证。 3、得理解包加载机制,基础的东西最重要。