分类 MiniProgram 下的文章

const wxuuid = function () {
  var s = [];
  var hexDigits = "0123456789abcdef";
  for (var i = 0; i < 36; i++) {
    s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
  }
  s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
  s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
  s[8] = s[13] = s[18] = s[23] = "-";
 
  var uuid = s.join("");
  return uuid
};

1. Vuex 状态管理

// store/index.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    cart: [] // 购物车数据
  },
  mutations: {
    addToCart(state, product) {
      state.cart.push(product);
    },
    removeFromCart(state, productId) {
      state.cart = state.cart.filter(item => item.id !== productId);
    },
    clearCart(state) {
      state.cart = [];
    }
  },
  getters: {
    cartItems: state => state.cart,
    cartTotal: state => state.cart.reduce((total, item) => total + item.price * item.quantity, 0),
  }
});

2. 本地存储(localStorage / uni.setStorage)

// 添加商品到购物车
function addToCart(product) {
  let cart = uni.getStorageSync('cart') || [];
  cart.push(product);
  uni.setStorageSync('cart', cart);
}

// 获取购物车数据
function getCart() {
  return uni.getStorageSync('cart') || [];
}

// 清空购物车
function clearCart() {
  uni.removeStorageSync('cart');
}

3. 在页面中使用 cartItems

<template>
  <view>
    <text>购物车商品列表:</text>
    <view v-for="item in cartItems" :key="item.id">
      <text>{{ item.name }} - {{ item.price }} (数量: {{ item.quantity }})</text>
    </view>
    <text>总价: {{ cartTotal }}</text>
  </view>
</template>

<script>
import { mapGetters } from 'vuex';

export default {
  computed: {
    ...mapGetters(['cartItems', 'cartTotal']), // 映射 Vuex getters
  },
  methods: {
    // 其他方法
  },
  mounted() {
    // 这里可以进行其他初始化操作
  }
};
</script>

<style scoped>
/* 添加你的样式 */
</style>

小结:mapGetters这是 Vuex 提供的一个辅助函数,可以让你在组件中方便地映射 Vuexgetters 到计算属性。通过这种方式,你可以直接使用 cartItemscartTotal 作为组件的计算属性。

创建 permission.js 文件:

//@unilts/permission.js

// 白名单
const whiteList = [
    '/', // 注意入口页必须直接写 '/'
    '/pages/tabbar/classify/classify', //分类
    '/pages/tabbar/cart/cart', //购物车
    {
        pattern: /^\/pages\/common\/*/
    } //支持正则表达式
];

export default async function() {
    const list = ['navigateTo', 'redirectTo', 'reLaunch', 'switchTab']
    // 用遍历的方式分别为,uni.navigateTo,uni.redirectTo,uni.reLaunch,uni.switchTab这4个路由方法添加拦截器
    list.forEach(item => {
        uni.addInterceptor(item, {
            invoke(e) {
                // 获取要跳转的页面路径(url去掉"?"和"?"后的参数)
                const url = e.url.split('?')[0]
                // 判断当前窗口是白名单,如果是则不重定向路由
                let pass
                if (whiteList) {
                    pass = whiteList.some((item) => {
                        if (typeof(item) === 'object' && item.pattern) {
                            return item.pattern.test(url)
                        }
                        return url === item
                    })
                }

                // 不是白名单并且没有token
                let token = uni.getStorageSync('Authorization');
                if (!pass && !token) {
                    // uni.showToast({
                    //     title: '请先登录',
                    //     icon: 'error'
                    // })
                    uni.redirectTo({
                        url: "/pages/common/login/login"
                    })
                    return false
                }
                return e
            },
            fail(err) { // 失败回调拦截
                console.log(err)
            }
        })
    })
}

1、在App.vue下使用:

import routingIntercept from '@/util/permission.js'
export default {
    onLaunch: function() {
        console.warn('当前组件仅支持 uni_modules 目录结构 ,请升级 HBuilderX 到 3.1.0 版本以上!');
        console.log('App Launch');
        // 对路由进行统一拦截,实现路由导航守卫 router.beforeEach 功能
        routingIntercept()
    },

2、在main.js下使用:

import routingIntercept from './utils/permission.js'


//对路由进行统一拦截,实现路由导航守卫router.beforeEach功能
routingIntercept()

注意:以上2种使用方式,任选其一即可。

uniapp(类微信小程序)生命周期函数如下,从dcloudio/uni-app导入。

onLoad
onShow
onReady
onHide
onUnload
onPullDownRefresh
onReachBottom



vue3组合式生命周期函数如下,从vue导入。

onMounted()
onUpdated()
onUnmounted()
onBeforeMount()
onBeforeUpdate()
onBeforeUnmount()
onErrorCaptured()
onRenderTracked()
onRenderTriggered()
onActivated()
onDeactivated()
onServerPrefetch()

问题:

微信小程序使用 echarts 时,控制台报错
[Component] : canvas 2d 接口支持同层渲染且性能更佳,建议切换使用。详见文档

原因:

echarts内部原因

解决办法:

1、修改源码 ec-canvas/ec-canvas.js

// before 
  data: {
    isUseNewCanvas: false
  },

// after  
  data: {
    isUseNewCanvas: true
  },

修改如上所示即可。

2、同时,需要组件调用方不能设置 force-use-old-canvas=“true”

<ec-canvas id="mychart-dom-bar" canvas-id="mychart-bar"   ec="{{ ec }}"></ec-canvas>

转自:https://blog.csdn.net/qubes/article/details/130660989

1、使用微信提供的证书工具生成微信支付商户证书

apiclient_cert.pem, apiclient_key.pem

2、使用 cmd 生成微信支付商户证书序列号

openssl x509 -in apiclient_key.pem -noout -serial

3、使用 cmd 生成微信支付平台证书 (需要 composer 安装 wechatpay/wechatpay)

# -k: 微信支付商户 APIv3 密钥, -m: 商户号, -f: 商户的私钥文件路径, -s: 商户证书序列号, -o: 平台证书保存路径
php vendor\bin\CertificateDownloader.php -k 03ea86*** -m 16442*** -f ***\storage\cert\apiclient_key.pem -s 1208B*** -o ***\Desktop\WXCertUtil\cert

4、完整配置信息

# 微信支付 APP
# APP ID
WECHAT_APP_ID=***
# 微信支付商户 ID
WECHAT_MCH_ID=***
# 微信支付商户 APIv2 密钥
WECHAT_MCH_SECRET=***
# 微信支付商户 APIv3 密钥
WECHAT_MCH_V3_SECRET=***
# 微信支付商户证书序列号
WECHAT_SERIAL=***
# 微信支付商户证书路径
WECHAT_CERT=***\storage\cert\apiclient_cert.pem
WECHAT_KEY=***\storage\cert\apiclient_key.pem
# 微信支付平台证书序列号
WECHAT_PLATFORM_SERIAL=***
# 微信支付平台证书路径
WECHAT_PLATFORM_PEM=***\storage\cert\wechatpay.pem

转自:https://learnku.com/articles/78016
感谢作者的辛苦付出。

直接上js代码,如下:

function Push(options) {
    this.doNotConnect = 0;
    options = options || {};
    options.heartbeat  = options.heartbeat || 25000;
    options.pingTimeout = options.pingTimeout || 10000;
    this.config = options;
    this.uid = 0;
    this.channels = {};
    this.connection = null;
    this.pingTimeoutTimer = 0;
    Push.instances.push(this);
    this.createConnection();
  }
  
  Push.prototype.checkoutPing = function() {
    var _this = this;
    setTimeout(function () {
        if (_this.connection.state === 'connected') {
            _this.connection.send('{"event":"pusher:ping","data":{}}');
            if (_this.pingTimeoutTimer) {
                clearTimeout(_this.pingTimeoutTimer);
                _this.pingTimeoutTimer = 0;
            }
            _this.pingTimeoutTimer = setTimeout(function () {
                _this.connection.closeAndClean();
                if (!_this.connection.doNotConnect) {
                    _this.connection.waitReconnect();
                }
            }, _this.config.pingTimeout);
        }
    }, this.config.heartbeat);
  };
  
  Push.prototype.channel = function (name) {
    return this.channels.find(name);
  };
  Push.prototype.allChannels = function () {
    return this.channels.all();
  };
  Push.prototype.createConnection = function () {
    if (this.connection) {
        throw Error('Connection already exist');
    }
    var _this = this;
    var url = this.config.url;
    function updateSubscribed () {
        for (var i in _this.channels) {
            _this.channels[i].subscribed = false;
        }
    }
    this.connection = new Connection({
        url: url,
        app_key: this.config.app_key,
        onOpen: function () {
            _this.connection.state  = 'connecting';
            _this.checkoutPing();
        },
        onMessage: function(params) {
            if(_this.pingTimeoutTimer) {
                clearTimeout(_this.pingTimeoutTimer);
                _this.pingTimeoutTimer = 0;
            }
  
            params = JSON.parse(params.data);
            var event = params.event;
            var channel_name = params.channel;
  
            if (event === 'pusher:pong') {
                _this.checkoutPing();
                return;
            }
            if (event === 'pusher:error') {
                throw Error(params.data.message);
            }
            var data = JSON.parse(params.data), channel;
            if (event === 'pusher_internal:subscription_succeeded') {
                channel = _this.channels[channel_name];
                channel.subscribed = true;
                channel.processQueue();
                channel.emit('pusher:subscription_succeeded');
                return;
            }
            if (event === 'pusher:connection_established') {
                _this.connection.socket_id = data.socket_id;
                _this.connection.state = 'connected';
                _this.subscribeAll();
            }
            if (event.indexOf('pusher_internal') !== -1) {
                console.log("Event '"+event+"' not implement");
                return;
            }
            channel = _this.channels[channel_name];
            if (channel) {
                channel.emit(event, data);
            }
        },
        onClose: function () {
            updateSubscribed();
        },
        onError: function () {
            updateSubscribed();
        }
    });
  };
  Push.prototype.disconnect = function () {
    this.connection.doNotConnect = 1;
    this.connection.close();
  };
  
  Push.prototype.subscribeAll = function () {
    if (this.connection.state !== 'connected') {
        return;
    }
    for (var channel_name in this.channels) {
        //this.connection.send(JSON.stringify({event:"pusher:subscribe", data:{channel:channel_name}}));
        this.channels[channel_name].processSubscribe();
    }
  };
  
  Push.prototype.unsubscribe = function (channel_name) {
    if (this.channels[channel_name]) {
        delete this.channels[channel_name];
        if (this.connection.state === 'connected') {
            this.connection.send(JSON.stringify({event:"pusher:unsubscribe", data:{channel:channel_name}}));
        }
    }
  };
  Push.prototype.unsubscribeAll = function () {
    var channels = Object.keys(this.channels);
    if (channels.length) {
        if (this.connection.state === 'connected') {
            for (var channel_name in this.channels) {
                this.unsubscribe(channel_name);
            }
        }
    }
    this.channels = {};
  };
  Push.prototype.subscribe = function (channel_name) {
    if (this.channels[channel_name]) {
        return this.channels[channel_name];
    }
    if (channel_name.indexOf('private-') === 0) {
        return createPrivateChannel(channel_name, this);
    }
    if (channel_name.indexOf('presence-') === 0) {
        return createPresenceChannel(channel_name, this);
    }
    return createChannel(channel_name, this);
  };
  Push.instances = [];
  
  function createChannel(channel_name, push)
  {
    var channel = new Channel(push.connection, channel_name);
    push.channels[channel_name] = channel;
    channel.subscribeCb = function () {
        push.connection.send(JSON.stringify({event:"pusher:subscribe", data:{channel:channel_name}}));
    }
    return channel;
  }
  
  function createPrivateChannel(channel_name, push)
  {
    var channel = new Channel(push.connection, channel_name);
    push.channels[channel_name] = channel;
    channel.subscribeCb = function () {
        __ajax({
            url: push.config.auth,
            type: 'POST',
            data: {channel_name: channel_name, socket_id: push.connection.socket_id},
            success: function (data) {
                data = JSON.parse(data);
                data.channel = channel_name;
                push.connection.send(JSON.stringify({event:"pusher:subscribe", data:data}));
            },
            error: function (e) {
                throw Error(e);
            }
        });
    };
    channel.processSubscribe();
    return channel;
  }
  
  function createPresenceChannel(channel_name, push)
  {
    return createPrivateChannel(channel_name, push);
  }
  
  /*window.addEventListener('online',  function(){
    var con;
    for (var i in Push.instances) {
        con = Push.instances[i].connection;
        con.reconnectInterval = 1;
        if (con.state === 'connecting') {
            con.connect();
        }
    }
  });*/
  
  
  function Connection(options) {
    this.dispatcher = new Dispatcher();
    __extends(this, this.dispatcher);
    var properies = ['on', 'off', 'emit'];
    for (var i in properies) {
        this[properies[i]] = this.dispatcher[properies[i]];
    }
    this.options = options;
    this.state = 'initialized'; //initialized connecting connected disconnected
    this.doNotConnect = 0;
    this.reconnectInterval = 1;
    this.connection = null;
    this.reconnectTimer = 0;
    this.connect();
  }
  
  Connection.prototype.updateNetworkState = function(state){
    var old_state = this.state;
    this.state = state;
    if (old_state !== state) {
        this.emit('state_change', { previous: old_state, current: state });
    }
  };
  
  Connection.prototype.connect = function () {
    this.doNotConnect = 0;
    if (this.networkState == 'connecting' || this.networkState == 'established') {
        console.log('networkState is ' + this.networkState + ' and do not need connect');
        return;
    }
    if (this.reconnectTimer) {
        clearTimeout(this.reconnectTimer);
        this.reconnectTimer = 0;
    }
  
    this.closeAndClean();
  
    var options = this.options;
    var _this = this;
    _this.updateNetworkState('connecting');
    var cb = function(){
         wx.onSocketOpen(function (res) {
            _this.reconnectInterval = 1;
            if (_this.doNotConnect) {
                _this.updateNetworkState('closing');
                wx.closeSocket();
                return;
            }
            _this.updateNetworkState('established');
            if (options.onOpen) {
                options.onOpen(res);
            }
        });
  
        if (options.onMessage) {
            wx.onSocketMessage(options.onMessage);
        }
  
        wx.onSocketClose(function (res) {
            _this.updateNetworkState('disconnected');
            if (!_this.doNotConnect) {
                _this.waitReconnect();
            }
            if (options.onClose) {
                options.onClose(res);
            }
        });
  
        wx.onSocketError(function (res) {
            _this.close();
            if (!_this.doNotConnect) {
                _this.waitReconnect();
            }
            if (options.onError) {
                options.onError(res);
            }
        });
    };
    wx.connectSocket({
        url: options.url,
        fail: function (res) {
            console.log('wx.connectSocket fail');
            console.log(res);
            _this.updateNetworkState('disconnected');
            _this.waitReconnect();
        },
        success: function() {
  
        }
    });
    cb();
  }
  
  Connection.prototype.connect = function () {
    this.doNotConnect = 0;
    if (this.state === 'connected') {
        console.log('networkState is "' + this.state + '" and do not need connect');
        return;
    }
    if (this.reconnectTimer) {
        clearTimeout(this.reconnectTimer);
        this.reconnectTimer = 0;
    }
  
    this.closeAndClean();
  
    var options = this.options;
  
    this.updateNetworkState('connecting');
  
    var _this = this;
    var cb = function(){
         wx.onSocketOpen(function (res) {
            _this.reconnectInterval = 1;
            if (_this.doNotConnect) {
                _this.updateNetworkState('disconnected');
                wx.closeSocket();
                return;
            }
            if (options.onOpen) {
                options.onOpen(res);
            }
        });
  
        if (options.onMessage) {
            wx.onSocketMessage(options.onMessage);
        }
  
        wx.onSocketClose(function (res) {
            _this.updateNetworkState('disconnected');
            if (!_this.doNotConnect) {
                _this.waitReconnect();
            }
            if (options.onClose) {
                options.onClose(res);
            }
        });
  
        wx.onSocketError(function (res) {
            _this.close();
            if (!_this.doNotConnect) {
                _this.waitReconnect();
            }
            if (options.onError) {
                options.onError(res);
            }
        });
    };
    wx.connectSocket({
        url: options.url+'/app/'+options.app_key,
        fail: function (res) {
            console.log('wx.connectSocket fail');
            console.log(res);
            _this.updateNetworkState('disconnected');
            _this.waitReconnect();
        },
        success: function() {
  
        }
    });
    cb();
  }
  
  Connection.prototype.closeAndClean = function () {
    if (this.state === 'connected') {
        wx.closeSocket();
    }
    this.updateNetworkState('disconnected');
  };
  
  Connection.prototype.waitReconnect = function () {
    if (this.state === 'connected' || this.state === 'connecting') {
        return;
    }
    if (!this.doNotConnect) {
        this.updateNetworkState('connecting');
        var _this = this;
        if (this.reconnectTimer) {
            clearTimeout(this.reconnectTimer);
        }
        this.reconnectTimer = setTimeout(function(){
            _this.connect();
        }, this.reconnectInterval);
        if (this.reconnectInterval < 1000) {
            this.reconnectInterval = 1000;
        } else {
            // 每次重连间隔增大一倍
            this.reconnectInterval = this.reconnectInterval * 2;
        }

        let online = false;
        wx.getNetworkType({
            success (res) {
              console.log(res)
              if(res.networkType !== 'none'){
                online = true;
              }
            }
        })
        // 有网络的状态下,重连间隔最大2秒
        if (this.reconnectInterval > 2000 && online) {
            _this.reconnectInterval = 2000;
        }
    }
  }
  
  Connection.prototype.send = function(data) {
    if (this.state !== 'connected') {
        console.trace('networkState is "' + this.state + '", can not send ' + data);
        return;
    }
    wx.sendSocketMessage({
        data: data
    });
  }
  
  Connection.prototype.close = function(){
    this.updateNetworkState('disconnected');
    wx.closeSocket();
  }
  
  var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) {d[p] = b[p];}
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  };
  
  function Channel(connection, channel_name) {
    this.subscribed = false;
    this.dispatcher = new Dispatcher();
    this.connection = connection;
    this.channelName = channel_name;
    this.subscribeCb = null;
    this.queue = [];
    __extends(this, this.dispatcher);
    var properies = ['on', 'off', 'emit'];
    for (var i in properies) {
        this[properies[i]] = this.dispatcher[properies[i]];
    }
  }
  
  Channel.prototype.processSubscribe = function () {
    if (this.connection.state !== 'connected') {
        return;
    }
    this.subscribeCb();
  };
  
  Channel.prototype.processQueue = function () {
    if (this.connection.state !== 'connected' || !this.subscribed) {
        return;
    }
    for (var i in this.queue) {
        this.queue[i]();
    }
    this.queue = [];
  };
  
  Channel.prototype.trigger = function (event, data) {
    if (event.indexOf('client-') !== 0) {
        throw new Error("Event '" + event + "' should start with 'client-'");
    }
    var _this = this;
    this.queue.push(function () {
        _this.connection.send(JSON.stringify({ event: event, data: data, channel: _this.channelName }));
    });
    this.processQueue();
  };
  
  ////////////////
  var Collections = (function () {
    var exports = {};
    function extend(target) {
        var sources = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            sources[_i - 1] = arguments[_i];
        }
        for (var i = 0; i < sources.length; i++) {
            var extensions = sources[i];
            for (var property in extensions) {
                if (extensions[property] && extensions[property].constructor &&
                    extensions[property].constructor === Object) {
                    target[property] = extend(target[property] || {}, extensions[property]);
                }
                else {
                    target[property] = extensions[property];
                }
            }
        }
        return target;
    }
  
    exports.extend = extend;
    function stringify() {
        var m = ["Push"];
        for (var i = 0; i < arguments.length; i++) {
            if (typeof arguments[i] === "string") {
                m.push(arguments[i]);
            }
            else {
                m.push(safeJSONStringify(arguments[i]));
            }
        }
        return m.join(" : ");
    }
  
    exports.stringify = stringify;
    function arrayIndexOf(array, item) {
        var nativeIndexOf = Array.prototype.indexOf;
        if (array === null) {
            return -1;
        }
        if (nativeIndexOf && array.indexOf === nativeIndexOf) {
            return array.indexOf(item);
        }
        for (var i = 0, l = array.length; i < l; i++) {
            if (array[i] === item) {
                return i;
            }
        }
        return -1;
    }
  
    exports.arrayIndexOf = arrayIndexOf;
    function objectApply(object, f) {
        for (var key in object) {
            if (Object.prototype.hasOwnProperty.call(object, key)) {
                f(object[key], key, object);
            }
        }
    }
  
    exports.objectApply = objectApply;
    function keys(object) {
        var keys = [];
        objectApply(object, function (_, key) {
            keys.push(key);
        });
        return keys;
    }
  
    exports.keys = keys;
    function values(object) {
        var values = [];
        objectApply(object, function (value) {
            values.push(value);
        });
        return values;
    }
  
    exports.values = values;
    function apply(array, f, context) {
        for (var i = 0; i < array.length; i++) {
            f.call(context || (window), array[i], i, array);
        }
    }
  
    exports.apply = apply;
    function map(array, f) {
        var result = [];
        for (var i = 0; i < array.length; i++) {
            result.push(f(array[i], i, array, result));
        }
        return result;
    }
  
    exports.map = map;
    function mapObject(object, f) {
        var result = {};
        objectApply(object, function (value, key) {
            result[key] = f(value);
        });
        return result;
    }
  
    exports.mapObject = mapObject;
    function filter(array, test) {
        test = test || function (value) {
            return !!value;
        };
        var result = [];
        for (var i = 0; i < array.length; i++) {
            if (test(array[i], i, array, result)) {
                result.push(array[i]);
            }
        }
        return result;
    }
  
    exports.filter = filter;
    function filterObject(object, test) {
        var result = {};
        objectApply(object, function (value, key) {
            if ((test && test(value, key, object, result)) || Boolean(value)) {
                result[key] = value;
            }
        });
        return result;
    }
  
    exports.filterObject = filterObject;
    function flatten(object) {
        var result = [];
        objectApply(object, function (value, key) {
            result.push([key, value]);
        });
        return result;
    }
  
    exports.flatten = flatten;
    function any(array, test) {
        for (var i = 0; i < array.length; i++) {
            if (test(array[i], i, array)) {
                return true;
            }
        }
        return false;
    }
  
    exports.any = any;
    function all(array, test) {
        for (var i = 0; i < array.length; i++) {
            if (!test(array[i], i, array)) {
                return false;
            }
        }
        return true;
    }
  
    exports.all = all;
    function encodeParamsObject(data) {
        return mapObject(data, function (value) {
            if (typeof value === "object") {
                value = safeJSONStringify(value);
            }
            return encodeURIComponent(base64_1["default"](value.toString()));
        });
    }
  
    exports.encodeParamsObject = encodeParamsObject;
    function buildQueryString(data) {
        var params = filterObject(data, function (value) {
            return value !== undefined;
        });
        return map(flatten(encodeParamsObject(params)), util_1["default"].method("join", "=")).join("&");
    }
  
    exports.buildQueryString = buildQueryString;
    function decycleObject(object) {
        var objects = [], paths = [];
        return (function derez(value, path) {
            var i, name, nu;
            switch (typeof value) {
                case 'object':
                    if (!value) {
                        return null;
                    }
                    for (i = 0; i < objects.length; i += 1) {
                        if (objects[i] === value) {
                            return {$ref: paths[i]};
                        }
                    }
                    objects.push(value);
                    paths.push(path);
                    if (Object.prototype.toString.apply(value) === '[object Array]') {
                        nu = [];
                        for (i = 0; i < value.length; i += 1) {
                            nu[i] = derez(value[i], path + '[' + i + ']');
                        }
                    }
                    else {
                        nu = {};
                        for (name in value) {
                            if (Object.prototype.hasOwnProperty.call(value, name)) {
                                nu[name] = derez(value[name], path + '[' + JSON.stringify(name) + ']');
                            }
                        }
                    }
                    return nu;
                case 'number':
                case 'string':
                case 'boolean':
                    return value;
            }
        }(object, '$'));
    }
  
    exports.decycleObject = decycleObject;
    function safeJSONStringify(source) {
        try {
            return JSON.stringify(source);
        }
        catch (e) {
            return JSON.stringify(decycleObject(source));
        }
    }
  
    exports.safeJSONStringify = safeJSONStringify;
    return exports;
  })();
  
  var Dispatcher = (function () {
    function Dispatcher(failThrough) {
        this.callbacks = new CallbackRegistry();
        this.global_callbacks = [];
        this.failThrough = failThrough;
    }
    Dispatcher.prototype.on = function (eventName, callback, context) {
        this.callbacks.add(eventName, callback, context);
        return this;
    };
    Dispatcher.prototype.on_global = function (callback) {
        this.global_callbacks.push(callback);
        return this;
    };
    Dispatcher.prototype.off = function (eventName, callback, context) {
        this.callbacks.remove(eventName, callback, context);
        return this;
    };
    Dispatcher.prototype.emit = function (eventName, data) {
        var i;
        for (i = 0; i < this.global_callbacks.length; i++) {
            this.global_callbacks[i](eventName, data);
        }
        var callbacks = this.callbacks.get(eventName);
        if (callbacks && callbacks.length > 0) {
            for (i = 0; i < callbacks.length; i++) {
                callbacks[i].fn.call(callbacks[i].context || (window), data);
            }
        }
        else if (this.failThrough) {
            this.failThrough(eventName, data);
        }
        return this;
    };
    return Dispatcher;
  }());
  
  var CallbackRegistry = (function () {
    function CallbackRegistry() {
        this._callbacks = {};
    }
    CallbackRegistry.prototype.get = function (name) {
        return this._callbacks[prefix(name)];
    };
    CallbackRegistry.prototype.add = function (name, callback, context) {
        var prefixedEventName = prefix(name);
        this._callbacks[prefixedEventName] = this._callbacks[prefixedEventName] || [];
        this._callbacks[prefixedEventName].push({
            fn: callback,
            context: context
        });
    };
    CallbackRegistry.prototype.remove = function (name, callback, context) {
        if (!name && !callback && !context) {
            this._callbacks = {};
            return;
        }
        var names = name ? [prefix(name)] : Collections.keys(this._callbacks);
        if (callback || context) {
            this.removeCallback(names, callback, context);
        }
        else {
            this.removeAllCallbacks(names);
        }
    };
    CallbackRegistry.prototype.removeCallback = function (names, callback, context) {
        Collections.apply(names, function (name) {
            this._callbacks[name] = Collections.filter(this._callbacks[name] || [], function (oning) {
                return (callback && callback !== oning.fn) ||
                    (context && context !== oning.context);
            });
            if (this._callbacks[name].length === 0) {
                delete this._callbacks[name];
            }
        }, this);
    };
    CallbackRegistry.prototype.removeAllCallbacks = function (names) {
        Collections.apply(names, function (name) {
            delete this._callbacks[name];
        }, this);
    };
    return CallbackRegistry;
  }());
  function prefix(name) {
    return "_" + name;
  }
  
  function __ajax(options){
    options=options||{};
    options.type=(options.type||'GET').toUpperCase();
    options.dataType=options.dataType||'json';
    params=formatParams(options.data);
  
    var xhr;
    if(window.XMLHttpRequest){
        xhr=new XMLHttpRequest();
    }else{
        xhr=ActiveXObject('Microsoft.XMLHTTP');
    }
  
    xhr.onreadystatechange=function(){
        if(xhr.readyState === 4){
            var status=xhr.status;
            if(status>=200 && status<300){
                options.success&&options.success(xhr.responseText,xhr.responseXML);
            }else{
                options.error&&options.error(status);
            }
        }
    }
  
    if(options.type==='GET'){
        xhr.open('GET',options.url+'?'+params,true);
        xhr.send(null);
    }else if(options.type==='POST'){
        xhr.open('POST',options.url,true);
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.send(params);
    }
  }
  
  function formatParams(data){
    var arr=[];
    for(var name in data){
        arr.push(encodeURIComponent(name)+'='+encodeURIComponent(data[name]));
    }
    return arr.join('&');
  }
  
  export default Push

感谢:
https://www.workerman.net/plugin/2
https://github.com/ljnchn/push/blob/main/src/push-wx.js

代码片段:

data:{
    waitTimes:0,//超时变量
    timeList:[],//定时器列表
},
myUpdate() {
    var maxWait = 10 //超时次数
    var newWait = this.data.waitTimes + 1 //执行的次数
    if (newWait >= maxWait) { //超时了
        console.log(util.formatTime(new Date()), '轮询超时')
    } else { //未超时
        var time = setTimeout(this.myUpdate, 2000)
        this.data.timeList.push(time) // 存储定时器
        console.log(util.formatTime(new Date()), '第', newWait, '次轮询中...')
        if (newWait === 6) { //拿到数据,轮询终止
            console.log(util.formatTime(new Date()), '拿到了所需数据!轮询停止')
            this.stopWaiting()
        } else { //继续轮询
            this.setData({
                waitTimes: newWait
            })
        }
    }
},
startWaiting() {
    setTimeout(this.myUpdate, 2000)
},
stopWaiting() {
    for (var i = 0; i < this.data.timeList.length; i++) {
        clearTimeout(this.data.timeList[i]); //清除了所有定时器
    }
}



/**
 * 生命周期函数--监听页面隐藏
 */
// 点击系统Home键返回上一步时候触发
onHide: function () {
  this.stopWaiting()
},

/**
 * 生命周期函数--监听页面卸载
 */
// 点击左上角返回箭头时候触发
onUnload: function () {
  this.stopWaiting()
},

转载:https://blog.csdn.net/qq_37398834/article/details/115675331
另一个参考:http://willless.com/settimeout-polling-in-applet-to-judge-data-jump-after-updating.html

onlaunch:当小程序初始化完成时,会触发 onLaunch(全局只触发一次)(app.js);
onLoad: 页面加载小程序注册完成后,加载页面,触发onLoad方法。一个页面只会调用一次,可以在 onLoad 中获取打开当前页面所调用的 query 参数(页面js)。
onShow: 页面显示页面载入后触发onShow方法,显示页面。每次打开页面都会调用一次(比如当小程序有后台进入到前台运行或重新进入页面时)。
onReady: 首次显示页面,页面初次渲染完成,会触发onReady方法,渲染页面元素和样式,一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。对界面的设置如wx.setNavigationBarTitle请在onReady之后设置。
onHide: 页面隐藏当navigateTo、底部tab切换、上传文件选择图片时调用。
onUnload: 页面卸载当返回上一页wx.navigateBack、wx.relanch、wx.redirectTo时都会被调用(这里的坑有点深)。

基本上可以说执行顺序为onLaunch–>onLoad–>onShow–>onReady–>onHide.虽然说onLaunch在onLoad之前执行,但是在onLaunch里请求获取是否有权限,等待返回值的时候Page里的onLoad事件就已经执行了。

解决办法:

在APP里面onLanch中的网络请求中设置判断
if (this.userInfoReadyCallback) {
    this.userInfoReadyCallback(res)
}

在page的onLoad中设置一个回调
app.userInfoReadyCallback = res => {
    if (res != '') {
        console.log("app.globalData.userInfo")
    }
}

转截:https://www.cnblogs.com/kaicy/p/14894777.html