我在D3中做了一件非常简单的事情,但是我遇到了代码执行顺序的奇怪问题。我正在使用一系列图像名称,循环遍历它们,并将每个svg
添加到父svg
作为g
元素。一切都很好。这是代码:
var names = ['a', 'b', 'c']
var over = d3.select('#overlay');
var w = 20;
for (var i = names.length - 1; i >= 0; i--) {
var x = w * i + w
console.log('1. '+ x)
d3.xml(names[i]+'.svg', function(error, xml) {
console.log('2. '+ x)
over.append('g')
.attr('transform','translate('+ x +','+ 20 +')')
.html(xml.getElementsByTagName('svg')[0].innerHTML)
})
}
但是,我遇到的变换问题都是一样的,并决定记录x来检查它。日志应该是这样的:
1. 60
2. 60
1. 40
2. 40
1. 20
2. 20
相反,它记录了这个:
1. 60
1. 40
1. 20
2. 20
2. 20
2. 20
有什么可能让这样的运行失序? d3.xml
调用是否异步?我无法理解。
答案 0 :(得分:2)
d3.xml()
是异步函数,并不是按预期顺序启动的,但稍后就足够了,循环结束并且x
的值为20.
您必须使用例如:
对值x
进行闭包
(function (x) {
d3.xml(names[i]+'.svg', function(error, xml) {
console.log('2. '+ x)
over.append('g')
.attr('transform','translate('+ x +','+ 20 +')')
.html(xml.getElementsByTagName('svg')[0].innerHTML)
});
})(x)
这样你就会进入控制台日志:
1. 60
1. 40
1. 20
2. 60
2. 40
2. 20