近来开发一个小程序的项目,遇到使用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 的执行会受很多方面的影响,数据到达视图层并不是实时的。

微信小程序setData()异常的更多相关文章

  1. 微信小程序 setData 的坑(转)

    最近在使用微信小程序的setData时,遇到了以下问题.如下: 官网文档在使用setData()设置数组对象的某个元素的属性时,是这么使用的: Page({ data: { array: [{text ...

  2. 微信小程序setData的使用,通过[...]进行动态key赋值

    首先先介绍一下微信小程序Page.prototype.setData(Object data, Function callback)的讲解: setData函数用于将数据从逻辑层发送到视图层(异步), ...

  3. 微信小程序setData复杂数组的更新、删除、添加、拼接

    众所周知,微信小程序里所有对数据的修改只有在setData里修改才会在页面上渲染.在此分享小程序里复杂数组的更新.删除.添加.拼接 初始数据 数组嵌套对象 data: { cartList = [{ ...

  4. 微信小程序 setData 如何修改动态数据?

    最近这段时间在写微信小程序,有一个页面需要动态修改 data 中的数据,而这里似乎是个坑. 1.正常修改 正常修改很简单,当触发 change 事件时,数据和页面都会同时发生改变.这个也不用多说,很简 ...

  5. 微信小程序支付异常:requestPayment:fail no permission

    今天在调试微信小程序支付时碰到了这个问题,支付参数都正常生成了,在调用 wx.requestPayment 进行支付时遇到了这个报错,查了一下发现是开发者工具中 AppID 写错了,用的 AppID ...

  6. 微信小程序setData子元素

    页面的数据中如果有子元素,如下图nowQuestion中的deleted元素 在小程序的setData中,不能直接用nowQuestion.deleted来设定它的值,而需要再定义一个变量承接 另外, ...

  7. 微信小程序 setData动态修改数据数组的值

    1.问题说明 有一组数据,用来存储图片路径,动态修改图片的路径来上传图片,而小程序JS只能通过事件获取时机和setData方法修改数据来改变view. 而用这样写的方式明显是错误的 2.解决办法 字符 ...

  8. 微信小程序setData()方法的详解以及对数组/json操作

    此篇文章是本人对setData方法的一些理解,是查阅文档和查找一些其他资料综述的,有所不足希望指正! 直接进入正题! 一.setData()方法: 1.参数接受一个对象,以key,value的形式表示 ...

  9. 微信小程序---setData

    data:{ obj:{ name:'hello' } } 对data中obj的name字段进行重新赋值. onLoad: function (option) { var value = 'obj.n ...

  10. 微信小程序setData()对数组的操作

    对于setData普通数据类型而言,没什么讲究 但是对于数组而言,再直接修改一个完整的数组显得有些多余,首先写着不简易,其次效率很是滴. 比如 你都能觉得复杂,官方肯定是有对应的优化的. 官方demo ...

随机推荐

  1. Day04笔记

    01.explicit的作用(了解) class Maker { public: //explicit只能放在构造函数前面,构造函数只有一个参数或其他参数有默认值时 explicit Maker(in ...

  2. Python地理分析库whitebox在Anaconda中的配置

      本文介绍在Anaconda环境下,安装Python中的一个高级地理空间数据分析库whitebox的方法.   首先,我们打开"Anaconda Prompt (Anaconda)&quo ...

  3. 从零开始学习 Java 系列之你为什么要学 Java?

    全文大约[4000]字,不说废话,只讲可以让你学到技术.明白原理的纯干货! 在正式开始本系列教程之前,壹哥希望先用一篇文章,来扫清你学习前的认知障碍.请坚定自己的学习信念,不要半途而废浪费时间,壹哥希 ...

  4. Spring Bean 的生命周期(详细解读)

    Spring Bean 的生命周期简单易懂.在一个 bean 实例被初始化时,需要执行一系列的初始化操作以达到可用的状态.同样的,当一个 bean 不再被调用时需要进行相关的析构操作,并从 bean ...

  5. 磁盘IO 基本常识

    计算机硬件性能在过去十年间的发展普遍遵循摩尔定律,通用计算机的 CPU主频早已超过3GHz,内存也进入了普及DDR4的时代.然而传统硬盘虽然在存储容量上增长迅速,但是在读写性能上并无明显提升,同时SS ...

  6. 计网学习笔记五 wireless && mobile networks

    老师把无线网络用一节课一遍过了-感觉没能学透,便课后自己总结,看书,找资料补充,把无线网络大概摸了个七七八八.虽然不算精细,但还能看!内容包括WLAN总概,WiFi-WLAN的实现,802.11规定的 ...

  7. (原创)【B4A】一步一步入门10:TabHost,标签页、标题带图标(控件篇06)

    一.前言 本篇教程我们来讲一下TabHost(标签页)的基本使用方法. 相信看完的你,一定会有所收获! 本文地址:https://www.cnblogs.com/lesliexin/p/1728556 ...

  8. pandas之字符串操作

    Pandas 提供了一系列的字符串函数,因此能够很方便地对字符串进行处理.在本节,我们使用 Series 对象对常用的字符串函数进行讲解.常用的字符串处理函数如下表所示: 函数名称 函数功能和描述 l ...

  9. mysql导出csv

    1.正常查询 SELECT a.emp_no '员工号',b.seq '文章序号' from vote_records a INNER JOIN vote_content b ON a.vote_co ...

  10. 频繁设置CGroup触发linux内核bug导致CGroup running task不调度

    1. 说明 1> 本篇是实际工作中linux上碰到的一个问题,一个使用了CGroup的进程处于R状态但不执行,也不退出,还不能kill,经过深入挖掘才发现是Cgroup的内核bug 2>发 ...