我想做的是:
JSON
文件,其中包含有关我的模型的数据以下是我的功能:
function getJSON(callback) {
var temp = $.getJSON("data/data.json", function(data) {
//execute the callback, passing it the data
callback(data);
});
}
function loadModels() {
//get our JSON
getJSON(function(data) {
//evaluate data
nodes = data.library[0].model.nodes;
nodesLen = nodes.length;
//Load nodes and add them to scene and array
for (var i = 0; i < nodesLen; i++) {
var url = nodes[i].url;
// PLY loader
var loader = new THREE.PLYLoader();
loader.load(url, function(geometry) {
geometry.computeFaceNormals();
var material = new THREE.MeshPhongMaterial({ color: 0xffffff, vertexColors: THREE.VertexColors, transparent: true, side: THREE.DoubleSide });
var mesh = new THREE.Mesh(geometry, material);
mesh.stepNum = i;
console.log(i);
mesh.position.x = 0;
mesh.position.y = 0;
mesh.position.z = 0;
//Add to scene
scene.add(mesh);
//Push into array
nodesArr.push(mesh);
});
}
});
}
问题:它们未正确加载。当我检查&#34; console.log(i)&#34;的输出时在PLY加载器中它返回的值始终相同。我认为在加载模型时,另一个循环已经开始了。如何指示循环在另一个循环开始之前等待所有函数完成?
答案 0 :(得分:1)
正如评论中已经提到的,这应该很好地解释了bahviour:JavaScript closure inside loops – simple practical example
问题基本上是这样的:函数loader.load()
是异步的,这意味着函数调用将立即返回并且不会等待来自网络的响应。因此,您的循环将立即完成(此时i
等于nodesLen
并且所有HTTP请求都已启动)。但是当时没有任何请求完成。这只会在此之后很长一段时间内发生(说微秒与数百毫秒),此时你的回调(function(geometry) {}
)最终会被第一次调用。
我在上面的链接中解释了一个解决方案:你可以使用一个闭包来密封&#34; i的当前值进入回调。这可能会解决您的问题,但您仍然会有很多并发请求(也不一定是坏事,浏览器可以处理它)。
但回答你的主要问题:如果你想等待下一个请求,直到完成上一个请求,你需要做这样的事情:
var remainingUrls = [ /* ... list of all model-urls ... */ ];
function loadNext() {
// get the first of the remaining urls and remove it from the array
var nextUrl = remainingUrls.shift();
if (!nextUrl) {
// when there is no next url, we are done here
return;
}
loader.load(nextUrl, function(geometry) {
addToScene(geometry);
// now it's time to start loading the next file
loadNext();
});
}
// start loading the whole list
loadNext();