和我之前的其他人一样,我在Javascript中与范围挣扎。 (那并尝试阅读这些蠢货)。我已经检查过这个问题的一些先前的线程,但我似乎无法让它们正确地应用到我的issuue。
在下面的示例中,我想在完全填充数组后操纵tagsArr
数组中的值。我将tagsArr变量声明在填充它的函数范围之外,以便全局访问它。但是变量似乎没有我期望的范围 - tagsArr.length
在我将其输出到第16行的控制台时为0。
$(function(){
var apiKey = [myapikey];
var tags = '';
var tagsArr = new Array();
$.getJSON('http://api.flickr.com/services/rest/?&method=flickr.people.getPublicPhotos&api_key=' + apiKey + '&user_id=46206266@N05&extras=date_taken,tags&format=json&jsoncallback=?', function(data){
$.each(data.photos.photo, function(i, item) {
var photoID = item.id;
$.getJSON('http://api.flickr.com/services/rest/?&method=flickr.photos.getInfo&api_key=' + apiKey + '&photo_id=' + photoID + '&format=json&jsoncallback=?', function(data){
if (data.photo.tags.tag != '') {
$.each(data.photo.tags.tag, function(j, item) {
tagsArr.push(item.raw);
});
}
});
tags = tagsArr.join('<br />');
console.debug(tagsArr.length);
});
$('#total-dragged').append(data.photos.total);
$('#types-dragged').append(tags);
});
});
答案 0 :(得分:2)
$ .getJSON是异步的(ajax中的a)。这意味着当你到达console.debug()时,getJSON仍然会得到。您需要在JSON回调中做一些额外的工作。
答案 1 :(得分:2)
您对getJSON的调用是异步的。因此,到达console.debug行时,对内部getJSON的所有调用仍然是未完成的。因此,数组长度仍为0。
最后的getJSON调用完成后,您需要运行一些额外的代码。
$(function(){
var apiKey = [myapikey];
var tags = '';
var tagsArr = new Array();
$.getJSON('http://api.flickr.com/services/rest/?&method=flickr.people.getPublicPhotos&api_key=' + apiKey + '&user_id=46206266@N05&extras=date_taken,tags&format=json&jsoncallback=?', function(data){
var totalExpected = data.photos.total;
var totalFetched = 0;
$.each(data.photos.photo, function(i, item) {
var photoID = item.id;
$.getJSON('http://api.flickr.com/services/rest/?&method=flickr.photos.getInfo&api_key=' + apiKey + '&photo_id=' + photoID + '&format=json&jsoncallback=?', function(data){
if (data.photo.tags.tag != '') {
$.each(data.photo.tags.tag, function(j, item) {
tagsArr.push(item.raw);
totalFetched += 1;
if (totalFetched == totalExpected)
fetchComplete();
});
}
});
function fetchComplete()
{
tags = tagsArr.join('<br />');
console.debug(tagsArr.length);
}
});
$('#total-dragged').append(data.photos.total);
$('#types-dragged').append(tags);
});
});
这可以假设照片的总数不超过默认的每页100个,否则你需要调整它。
那就是说我不认为使用.each来解决大量的getJSON请求是很有意义的。我会重构它,以便在任何时候只有一次调用getJSON。将下一张照片的下一个getJSON回复到一个问题,直到所有照片都被拉出然后完成您的完整代码。
答案 2 :(得分:1)
这不是范围问题 - 问题是getJSON
是异步的,所以它在将请求发送到flickr后立即继续执行。当浏览器执行console.debug
时,请求尚未返回,并且您尚未完成处理响应(因此尚未将任何项目推送到数组中)。
要解决此问题,请找到应该仅在阵列已满时执行的所有代码,并将其移至getJSON
回调方法中:
if (data.photo.tags.tag != '') {
$.each(data.photo.tags.tag, function(j, item) {
tagsArr.push(item.raw);
});
tags = tagsArr.join('<br />');
console.debug(tagsArr.length);
$('#total-dragged').append(data.photos.total);
$('#types-dragged').append(tags);
}
答案 3 :(得分:1)
原因是getJSON
是异步请求。在调用$.getJSON
之后,javascript引擎将立即移动到以下两行代码,并输出数组的长度,到那时为零长度。直到那之后,getJSON
请求才会收到响应,并将项添加到数组中。
答案 4 :(得分:1)
getJSON函数是异步的,因此当您调用debug函数时,数组仍然为空,因为请求未完成。使用$ .ajax函数并设置async:false,它将起作用。
$.ajax({
type: "GET",
url: 'http://api.flickr.com/services/rest/?&method=flickr.photos.getInfo&api_key=' + apiKey + '&photo_id=' + photoID + '&format=json&jsoncallback=?',
dataType: "json",
async:false,
success:function(data){
if (data.photo.tags.tag != '') {
$.each(data.photo.tags.tag, function(j, item) {
tagsArr.push(item.raw);
});
}
}
});
答案 5 :(得分:0)
您可能需要查看this question I posted的答案。 javascript中有关于范围问题的一些很好的信息。