一、export 与 exports的区别

1. module.exports和exports是属于 CommonJS 模块规范。CommonJS规范规定,每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。

2. Node应用由模块组成,采用CommonJS模块规范。根据这个规范,每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。为了方便,Node为每个模块提供一个exports变量,指向module.exports。这等同在每个模块头部,有一行这样的命令。

// exports其实是module.exports的引用 ,可以直接在exports对象上添加相关的方法。    
var exports = module.exports;

3. module.exports和exports导出模块,用require引入模块

var Redis = require('./redis.js');

// redis.js

var redis= "redis"

/**
 * 设置
 * k 键key
 * v 值value
 * t 秒
 */
function put(k, v, t) {
      wx.setStorageSync(k, v)
      var seconds = parseInt(t)
      if (seconds > 0) {
          var newtime = Date.parse(new Date())
          newtime = newtime / 1000 + seconds;
          wx.setStorageSync(k + redis, newtime + "")
      } else {
       		wx.removeStorageSync(k + redis)
      }
}

/**
 * 获取
 * k 键key
 */
function get(k) {
    var deadtime = parseInt(wx.getStorageSync(k + redis))
    if (deadtime) {
        if (parseInt(deadtime) < Date.parse(new Date()) / 1000) {
          wx.removeStorageSync(k);
          return null
        }
    }
    var res=wx.getStorageSync(k)
    if(res){
      	return res
    }else{
     		return null
    }
}

/**
 * 删除
 */
function remove(k) {
    wx.removeStorageSync(k);
    wx.removeStorageSync(k + redis);
}
 
/**
 * 清除所有key
 */
function clear() {
  	wx.clearStorageSync();
}

// 导出模块函数
module.exports={
  put,
  get,
  remove,
  clear
}

4. export和export default是属于ES6语法。export和export default导出模块,import导入模块。

模块文件中定义并导出函数:

export function FunctionName(options) {}

引入模块函数:

指定导入:import { func1, func2 } from './api.js';

全部导入:import * as api from './api'   // api.js 文件后缀名可省略

// api.js

/**
 * 自定义 Error 类
 *
 * code == 0 正确
 * code > 0 HTTP 请求,服务器端返回的错误码
 * code == -1 HTTP 请求,服务器返回的数据格式不正确,服务器错误
 */
export function MyError(message, code, extra) {
    if (!Error.captureStackTrace) {
   		 this.stack = (new Error()).stack;
    } else {
   			Error.captureStackTrace(this, this.constructor);
    }
    this.message = message;
    this.code = code;
    this.extra = extra;
}

MyError.prototype = new Error();
MyError.prototype.name = 'MyError';
MyError.prototype.constructor = MyError;
export const CancelAuthError = new MyError('没有授权', -100);

5. exports 与 export 用法对比

(1)CommonJS:

         导出 module.exports=... 或 exports=...

         导入 require

(2)ES6:导出
         导出 export ...   或  export default ...

         导入 import

二、promise封装wx对象方法

// api.js

// 把 wx 对象里的方法(传入参数中包含 success 和 fail)转换为返回 promise 的方法
function promisifyWx(name) {
    return function (param) {
        return new Promise((resolve, reject) => {
            let base = {
                success: (res) => {
                    resolve(res);
                },
                fail: (err) => {
                    reject(new MyError(err.errMsg, -1));
                }
            };
            // Object.assign(target, ...sources) :target ->目标对象   source->源对象 返回target
            // 即复制属性param, base 到target对象{}中
            wx[name](Object.assign({}, param, base));
        });
    };
}

// 定义与 微信小程序 同名对象wx
exports.wx = {};

// 将wx对象的方法经promise封装后作为当前模块属性 exports.wx
for (let name in wx) {
    exports.wx[name] = promisifyWx(name);
}

/**
 * 对封装后的 exports.wx.request 方法进一步处理
 */
export function request(url, param, callback) {
    let p = exports.wx.request({
        url,
        method: 'POST',
        data: param
    }).then(res => {
        let resBody = res.data;
        if (resBody && typeof resBody === 'object') {
            if (resBody.code === 0) {
                return resBody.data;
            } else if (resBody.code == -1) {
                wx.showToast({
                    title: resBody.msg,
                    icon: "none",
                    duration: 2000, // 提示的延迟时间,单位毫秒,默认:1500 
                    mask: true, // 是否显示透明蒙层,防止触摸穿透,默认:false 
                    success: function () {},
                    fail: function () {},
                    complete: function () {
                        setTimeout(function () {
                            wx.reLaunch({
                                url: '/pages/index/index',
                            })
                        }, 2000)
                    }
                })
            }
            let message = resBody.msg || '服务器错误';
            let extra;
            if (message.length > 50) {
                extra = message;
                message = '服务器错误';
            }
            throw new MyError(message, resBody.code, extra);
        } else {
            throw new MyError('服务器错误', -1, resBody);
        }
    }, err => {
        throw new MyError('没有网络连接或服务器错误', err.code, err);
    });

    if (typeof callback === 'function') {
        // 用回调函数接收返回结果
        p.then(res => callback(null, res), callback);
    } else {
        // 直接接收返回数据结果
        return p;
    }
}

// 引用promise函数

import * as Api from './api' 

Api.request(url, param).then(res => {
   // do something
})

三、promise为何物

Promise 是抽象的异步处理对象,其构造⽅法:

// Promise 构造函数接受⼀个函数作为参数,该函数的两个参数分别是 resolve 和 reject
let promise = new Promise((resolve, reject) => {
			resolve(); //异步处理
});

Promise 有三个状态:

1. Fulfilled: has-resolved, 表⽰成功解决,这时会调⽤ onFulfilled.

2. Rejected: has-rejected, 表⽰解决失败,此时会调⽤ onRejected.

3. Pending: unresolve, 表⽰待解决,既不是resolve也不是reject的状态。也就是promise对象刚被创建后的初始化状态

  • resolve函数的作⽤是,将 Promise 对象的状态从 未处理 变成 处理成功 (unresolved => resolved), 在异步操作成功时调⽤,并将异步操作的结果作为参数传递出去。
  • reject函数的作⽤是,将 Promise 对象的状态从 未处理 变成 处理失败 (unresolved => rejected), 在异步操作失败时调⽤,并将异步操作报出的错误,作为参数传递出去。

Promise 实例⽣成以后,可以⽤ then ⽅法和 catch ⽅法分别指定 resolved 状态和 rejected 状态的回调函数。

构造⽅法中的两个参数resolve, reject即为改变promise的状态,resolve ⽅法把 Promise 的状态置为完成态(Resolved),这时 then ⽅法就能捕捉到变化,并执⾏“成功”情况的回调。resolve, reject可抛出结果,作为then⽅法中函数的参数。

then可接受两个参数,第⼀个处理Resolved状态的函数,第⼆个处理Rejected函数。如果只想处理成功,或者失败,对应参数可设置为null,只有⼀个参数则表⽰状态改变就执⾏,不区分状态结果。

  • catch()⽅法,用于捕捉js执行出现异常时,可以⽤来指定 reject 的回调。
  • all()⽅法,提供了并⾏执⾏异步操作的能⼒,并且在所有异步操作执⾏完后才执⾏回调, 会把所有异步操作的结果放进⼀个数组中传给 then。
  • race()⽅法,⽤法与 all ⼀样,只不过 all 是等所有异步操作都执⾏完毕后才执⾏ then 回调,⽽ race 的话只要有⼀个异步操作执⾏完毕,就⽴刻执⾏ then 回调,其它没有执⾏完毕的异步操作仍然会继续执⾏。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐