node.addChild执行难道不是同步的吗?问题很怪异

node.addChild()执行不是同步的吗?

代码如下:

var dialogNode = cc.instantiate(prefab);
this.node.addChild(dialogNode);
cc.log("add完毕");
var dialogComponent = dialogNode.getComponent("xxx");
dialogComponent.init();

prefab的 xxx 组件 onload里写的:
cc.log(" loaded... ");

prefab的 xxx 组件 init 里写的:
cc.log(" init... ");

结果为:
add完毕
init…
loaded…

是什么问题呢?

addChild 是同步的,但是组件 onLoad 在组件激活过程中调用,参考文档

http://cocos.com/docs/creator/scripting/life-cycle-callbacks.html

已经 this.node.addChild(dialogNode);
不算激活吗,激活的含义是什么?

此时 this.node 在场景中吗?是已经激活的节点吗?

creator 1.4.0正式版

是的,this.node 是常驻节点,而且是在上个场景中常驻的,确定已经在场景中。

var dialogNode = cc.instantiate(prefab);
this.node.addChild(dialogNode);
cc.log("add完毕");
var dialogComponent = dialogNode.getComponent("xxx");
dialogComponent.init();

这段代码是写在常驻节点的组件上的,常驻节点上 on 了一个消息接收, 收到消息后调用上述代码


补充:

太奇怪了:
init代码里写上:

其中 this.titleNode是在prefab组件的onload中初始化的

执行结果是:

补充:
又测试了下,在常驻节点常驻的那个场景是没有问题的,换其他场景就有这个问题。

再次补充:
setTimeout(() => {
dialogComponent.init();
}, 0);
顺序就正常了,但原因没找到不能这么凑合啊。。。。。。

@jare 会不会是常驻节点有问题?

抱歉我没看出什么原因。我怀疑是这个常驻节点在场景中存在多份?最好上传一个 demo 看看。

常驻节点确定为同一实例,因为我打印了常驻节点的 uuid,是一样的

第二次打印UUID后调用的 组件的 init , init 里面有访问onload里面初始化的数据,现在onload 在init后执行了, 所以访问不到就报错了,这也是我提这个问题的原因。

发个 demo 来吧

好吧,不过代码链太长,不知道写demo能不能复现。。

@jare @panda

demo.rar (156.8 KB)

我看了一下代码,出错原因是进入 Login 场景时,你在 onLoad emit 了其它组件的 showDialog 消息。这时其它节点的 onLoad 还没有被执行到。
这是正常的,目前 onLoad 之间的调用顺序是不保证的。在 1.5 才能设置脚本的初始化优先级。

常驻节点加载后切换场景还要先销毁再加载吗?

不用 asdf