微信小程序setData()异常

近来开发一个小程序的项目,遇到使用setData()始终报错的情况,其问题奇特难解…

一、操作错误截图

在这里插入图片描述

如上图,只要将setData放置在回调函数中就会出现异常,如果不放在回调中就正常;
好郁闷,why? 难道是官方的Page.prototype.setData(Object data, Function callback)有问题?这个好像也不太可能。我其他页面也在用呀!
纠结好久,老是报错,一直不明白他为什么要这样对我,麻蛋。
最后将该方法拷贝到其他页面运行测试发现没问题!!!
why? 这又是唱的哪一出呀?
于是我开始了漫漫排错路
我采用了最简单的排除注释大法
果不其然,很快就定位到了原来是使用echarts (看这篇博客:小程序使用echarts 在一个页面打印多个饼图的坑)留下的祸患

二、错误代码片段

1、初始化echarts
  /**
 * 初始化echats
 * 使用promise获取初始化echarts 实例
 * @return {Object} echart
 * 
 */
  initChart: function (canvas, width, height) {
    return new Promise(resolve => {
      const chart = echarts.init(canvas, null, {
        width: width,
        height: height
      });
      canvas.setChart(chart);
      chart.setOption(optionConfig);
      resolve(chart);
    });
  },

2、缓存echarts 实例
  // 初始化【数据来源echarts】
  echartInit_source(e) {
     this.initChart(e.detail.canvas, e.detail.width, e.detail.height).then(res => {
       this.data.initchartSource = res;
       // 判断所以echarts 实例都初始完毕;并且invokePrintPie为false
       if (this.data.initchartType && this.data.initchartSource && this.data.initchartModel && !this.data.invokePrintPie){
       //  this.getPieDataAndPrintGraph(); // 打印饼图
         this.data.invokePrintPie = true;
       }
       return res;
    });
  },

根据排查确定错误出在this.data.initchartSource = res;将echarts 实例挂载到data中出的错
该保存echarts 实例目的是为了在后台数据返回后更新option,具体请参考: 小程序使用echarts 在一个页面打印多个饼图的坑

三、问题修复

既然data挂载会异常,那就把它挂载到全局app中去

1、修改后的代码片段

var g_app = getApp();
Page({
  // 初始化【数据来源echarts】
  echartInit_source(e) {
     this.initChart(e.detail.canvas, e.detail.width, e.detail.height).then(res => {
      //  this.data.initchartSource = res;
       g_app.source_echart_obj = res;
       // 判断所以echarts 实例都初始完毕;并且invokePrintPie为false
       if (g_app.source_echart_obj && g_app.type_echart_obj && g_app.model_echart_obj && !this.data.invokePrintPie){
        this.getPieDataAndPrintGraph(); // 打印饼图
         this.data.invokePrintPie = true;
       }
       return res;
    });
  },
})

再测试问题解决,OK。

只是最后还是没有弄清楚问题的最终由来,根据如下setData官方对其工作原理的介绍推测应该是echarts 实例中引用 了data实例
然而我们又使用data来挂载echarts 实例,so当在使用setData来更新其他数据时;其js会一层一层根据引用去查找对象,当对象循环被引用就会出现Converting circular structure to JSON

工作原理
小程序的视图层目前使用 WebView 作为渲染载体,而逻辑层是由独立的 JavascriptCore 作为运行环境。在架构上,WebView 和 JavascriptCore 都是独立的模块,并不具备数据直接共享的通道。当前,视图层和逻辑层的数据传输,实际上通过两边提供的 evaluateJavascript 所实现。即用户传输的数据,需要将其转换为字符串形式传递,同时把转换后的数据内容拼接成一份 JS 脚本,再通过执行 JS 脚本的形式传递到两边独立环境。
而 evaluateJavascript 的执行会受很多方面的影响,数据到达视图层并不是实时的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奔跑的痕迹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值