我当前的<body>...<script>....</script></body>
标签包含以下内容:
<script>
$(document).ready(function(){
function main(){
var urlOne = 'https:....';
var summaryTable = {};
var distinctKeys = [];
$.getJSON(urlOne, function(jsonOne) {
// write code to collect data from urlOne and put it in 'summaryTable' AND 'distinctKeys'
distinctKeys.append(jsonOne['something']);
}); // end of first getJSON
/* ****** the javascript would NOT execute anything below this **** */
var foo = distinctKeys.length;
for (var i = 0; i < foo; i++) {
var curUrl = urlConstant + distinctKeys[i];
$.getJSON(curUrl, function(jsonTwo) {
// do stuff to add more info into 'summaryTable'
}); // end of second getJSON
}; // end of for loop
}; // end of main()
main();
}); // end of all javascript code
</script>
正如我上面提到的,代码不会继续执行/* ****** the javascript would NOT execute anything below this **** */
行以下的任何内容。我注意到,distinctKeys
和summaryTable
在执行第一个$.getJSON
调用后仍然为空。我想以特定的顺序拨打getJSON
两次 - 第二次是根据第一次通话中获得/收集的信息。谁能解释我怎么能做到这一点?
先谢谢您的回答!
答案 0 :(得分:1)
您可以使用解决方案
var urlArray = ['https://one.com', 'https://two.com', 'https://three.com'];
var i = 0;
var getJSONData = function(){
$.getJSON(urlArray[i], function(data){
console.log(data);
i++;
if( i < urlArray.length)
getJSONData();
});
};
您的语法错误var urlArray = ['https://one.com', 'https://two.com', 'https://three.com];
,错过了single quote
。
我建议不要在getJSON
中使用for loop
方法,而是将其置于方法&amp;一旦从AJAX调用和getting the url's use a variable
收到数据,就调用该方法。
根据更新的问题更新了答案
$(document).ready(function(){
function main(){
var urlOne = 'https:....';
var summaryTable = {};
var distinctKeys = [];
var i = 0;
$.getJSON(urlOne, function(jsonOne) {
// write code to collect data from urlOne and put it in 'summaryTable' AND 'distinctKeys'
distinctKeys.append(jsonOne['something']);
getJSONData(); // this will be used to call for the first time.
}); // end of first getJSON
var getJSONData = function(){
var curUrl = urlConstant + distinctKeys[i];
$.getJSON(curUrl, function(data){
console.log(data);
i++;
if( i < distinctKeys.length)
getJSONData();
});
};
}; // end of main()
main();
}); // end of all javascript code
希望这会对你有所帮助。
答案 1 :(得分:1)
Javascript中的异步函数不会阻止代码 执行。它允许程序流进入下一个语句 不立即执行功能块内部的操作。什么时候 它有一些响应,异步调用内部的函数得到 执行。因此名称
callback
起作用。
在您的情况下,function(jsonOne) {
是一个回调函数,在您从服务器获得响应后执行该函数。
以上陈述的一个小例子:
var data = [];
$.getJSON('https://adobe.github.io/Spry/data/json/array-01.js', function(data) {
console.log("JSON output length is", data.length);
});
console.log("JSON output length is", data.length);
执行此操作将首先记录JSON output length is 0
,然后记录JSON output length is 5
。这解释了Javascript如何处理异步调用。
还要注意,我们在回调外访问的数据变量与我们在回调内访问的数据变量不同。回调内的变量数据只能在回调内访问,因为Javascript变量具有功能范围。它们的范围仅限于声明它们的功能。
下一个问题是使用for循环调用异步函数。到目前为止,很明显,即使在第一次getJSON调用得到响应之前,for循环也会完成执行。
因此,如果您计划在响应回调中使用i的值, 您将始终获得所有getJSON的终止值 回应回调。
示例代码:
for (var i=0; i<5; i++) {
$.getJSON('https://adobe.github.io/Spry/data/json/array-01.js', function(jsonData) {
console.log("Iteration number", i);
});
}
输出将记录Iteration number 5
所有5次迭代。这是因为你的for循环甚至在第一次调用getJSON之前就调用了5 getJSON。
解决方案是利用Javascript的功能范围。
for (var i=0; i<5; i++) {
(function(x) {
$.getJSON('https://adobe.github.io/Spry/data/json/array-01.js', function(jsonData) {
console.log("Iteration number", x);
});
)(i);
}
这可以在javascript中使用immediately invoked anonymous functions
。基本上在循环中,您调用函数而不是直接调用getJSON。对于此函数,您将i作为参数传递。在函数内部,我可以作为x访问。在函数内部,调用函数时i的值保留为x。
对于专家Javascript Ninjas,我更喜欢匿名函数,因为 我不想通过声明一个函数来污染全局命名空间 这个不重复的任务。我知道效率会受到打击但是它会受到影响 对于少数我来说应该没问题。
@ user1330974:这可能不是您期望的直接答案,但一旦您理解了这个概念,您就可以自己解决问题。