近来开发一个小程序的项目,遇到使用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. Java8 lambda常用操作

    参考博客:https://www.cnblogs.com/hmy-1365/p/12923435.html

  2. ABAP 调用HTTP上传附件(二)之中文乱码

    1.这篇文章的由来 之前已经发表了<ABAP 调用HTTP上传附件>的文章,详细介绍了如何通过HTTP请求传输附件,可点击链接参考原有文档 因为之前对传输文件的中文文件名处理上解释不够详细 ...

  3. 获得New Bing资格后,在Ubuntu环境下使用New Bing

    技术背景 如今基于GPT-4的New Bing,结合搜索引擎的功能,可以说已经达到了非常高的智力水平.虽说ChatGPT的出现打击了很多的行业,但是对我们来说也未必不是一种机遇.合理的使用ChatGP ...

  4. scoket用法

    一.scoket基本介绍 1.scoket简介(以下是来自chatgpt回答) 1)Socket(套接字)是计算机网络中用于描述主机之间通信的一种机制.它定义了一种标准的接口, 使得应用程序可以利用网 ...

  5. 多态、抽象、Object类

    1.方法重写要求:方法名相同.参数类型相同.返回值相同或其子类返回值相同,子类修饰符要不小于父类 2.方法重载要求:方法名相同.参数类型不同.返回值没有改变.修饰符无关 3.多态的前提是继承.多态是定 ...

  6. shell读取配置文件-sed命令

    在编写启动脚本时,涉及到读取配置文件,特地记录下shell脚本读取启动文件的方式.主要提供两种格式的读取方式,方式一配置文件采用"[]"进行分区,方式二配置文件中需要有唯一的配置项 ...

  7. Kubernetes客户端认证(二)—— 基于ServiceAccount的JWTToken认证

    1.概述 在 Kubernetes 官方手册中给出了 "用户" 的概念,Kubernetes 集群中存在的用户包括 "普通用户" 与 "Service ...

  8. python选出一定数量的随机文件到某个文件夹

    import os import random import shutil def move_file(target_path, save_path, number): file_list = os. ...

  9. 基于Containerd容器引擎和kubeadm工具部署K8sv1.26.3

    前文我了解了基于ubuntu2204部署containerd容器引擎以及containerd客户端工具的部署和使用相关话题,回顾请参考:https://www.cnblogs.com/qiuhom-1 ...

  10. Network Science:巴拉巴西网络科学学习笔记3——第二章随机网络

    第二章:随机网络Erdős-Rényi Network (ER网络) 随机网络的两种定义形式: \(G(N,L)\)模型:N个节点,L条边随机链接. \(G(N,p)\)模型:N个节点,每个节点之间以 ...