我注意到这段代码无法正常工作。
消息RENDER_IMAGE在有效负载中使用不同的图像多次广播,但下面代码中的self.model.get(“image”)始终返回最后一个图像。为什么?
bus.subscribe("RENDER_IMAGE", (message, payload) => {
const self = this;
self.model.set(payload);
self.render().then(function() {
bus.broadcast("IMAGE_RENDER_COMPLETE", self.model.get("image"));
});
});
同时此代码的工作正确:
bus.subscribe("RENDER_IMAGE", (message, payload) => {
const self = this;
self.model.set(payload);
const image = self.model.get("image"));
self.render().then(function() {
bus.broadcast("IMAGE_RENDER_COMPLETE", image;
});
});
答案 0 :(得分:1)
在第一个示例中,您将在渲染完成后从模型中检索image
字段。
与此同时,在第一次渲染完成之前,可能会触发一个或多个RENDER_IMAGE
事件。每当此类事件触发时,您都在更新image
字段。
即。发生类似这样的事情
RENDER_IMAGE triggered
Set image field (image = 0)
Start render (0)
RENDER_IMAGE triggered
Set image field (image = 1)
Start render (1)
Render finished (0)
Get image field (1, because image = 1)
Render finished (1)
Get image field (1, because image = 1)
在第二个示例中,您在设置后立即检索image
。由于JavaScript是单线程的,因此在self.model.set(payload);
执行之前不可能调用另一个const image = self.model.get("image"));
:
RENDER_IMAGE triggered
Set image field (image = 0)
Get image field (0, because image = 0)
Start render (0)
RENDER_IMAGE triggered
Set image field (image = 1)
Get image field (1, because image = 1)
Start render (1)
Render finished (0)
Render finished (1)
如果您仍然想知道为什么直接访问模型和使用变量之间存在差异:事件处理程序的每次调用都有自己的 image
变量,但他们都访问相同的共享模型。
这是共享数据的特征之一,这就是为什么在处理异步流程时必须小心处理共享数据的原因。