.push 内部函数后全局数组未更新
Global array not updating after .push inside function
嘿伙计们谁能帮助我?
基本上我想制作一个循环遍历 newsWire 数组并自动更新文本的突发新闻页脚。问题是当我 运行 我的 console.log(newsWire.length) 在 loadNewswire 函数之外它 returns a 0,而 console.log 在 returns 40 作为应该吗?
Link: http://jsfiddle.net/u8y8zh72/3/
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<style>
footer {
height: 75px;
position: fixed;
bottom: 0;
}
</style>
</head>
<body>
<div class="container">
<ul id="js-news" class="js-hidden"></ul>
</div>
<footer>
<div class="container" id="newswiretxt">
<span></span>
</div>
</footer>
</body>
<script type="text/javascript">
var newsWire = [];
function loadNewswire() {
$.getJSON('http://api.nytimes.com/svc/news/v3/content/all/all.json',
{'api-key': 'XXXXXXXXX'},
function(data) {
console.log(data)
var newsWireTemp = [];
for (var i = 0; i < data.results.length; i++) {
var breakingNews = data.results[i];
var breakingTitle = breakingNews.title;
var breakingAbstract = breakingNews.abstract;
newsWireTemp.push(breakingTitle);
newsWireTemp.push(breakingAbstract);
}
newsWire = newsWireTemp;
console.log(newsWire.length);
});
}
loadNewswire();
console.log(newsWire.length);
$(document).ready(function() {
var items = newsWire;
$text = $('#newswiretxt span'),
delay = 10; //seconds
function loop (delay) {
$.each(items, function (i, elm){
$text.delay(delay*1E3).fadeOut();
$text.queue(function(){
$text.html(items[i]);
$text.dequeue();
});
$text.fadeIn();
$text.queue(function(){
if (i == items.length -1) {
loop(delay);
}
$text.dequeue();
});
});
}
loop(delay);
});
</script>
主要是这个:
...
loadNewswire();
console.log(newsWire.length);
...
当您调用 loadNewsWire
时,您正在启动一个异步 JSON 请求。但是,脚本执行不会等待该函数完成,因此它会立即运行以下 console.log
语句。那时,JSON 请求还没有完成,所以 newsWire
数组仍然是空的——这就是为什么 console.log(newsWire.length)
returns 0 在那里。
在您的 loadNewsWire
函数中,您有一个回调函数,该函数会在 JSON 请求已 return 编辑了您的数据时执行。此时您正在填充数组,console.log(newsWire.length)
为您提供预期的计数。
更新回复评论:
Is there anyway to make the rest of my code wait for the function to
execute?
是的! $.getJSON
是 $.ajax
的便利包装器,它 return 是一个 jqXHR
对象(jQuery documentation 中有完整有趣的细节)。您可以向该对象添加额外的回调,这就是您在对 $.getJSON
的调用中实际执行的内联操作。以下:
$.getJSON('http://...', { 'api-key': '...' },
function (data) {
// stuff
});
相当于:
$.getJSON('http://...', { 'api-key': '...' })
.done(function (data) {
// stuff
});
因此,如果您将 loadNewswire
修改为 return 从 $.getJSON
编辑的对象 return,您可以为其附加一个回调,等待异步操作完成,并将其余代码放入其中。如果您将代码更改为:
function loadNewswire() {
return $.getJSON(
...
);
};
然后您可以使用 done
、fail
或 always
回调之一包装您要等待的代码。
您的调用代码将如下所示:
loadNewswire().done(function () {
console.log(newsWire.length);
// and any other code you want to hold until the async operation is complete
});
我建议通读 previously mentioned documentation - 它有点沉重,但它很好地概述了如何使用 jQuery.
处理异步请求
嘿伙计们谁能帮助我? 基本上我想制作一个循环遍历 newsWire 数组并自动更新文本的突发新闻页脚。问题是当我 运行 我的 console.log(newsWire.length) 在 loadNewswire 函数之外它 returns a 0,而 console.log 在 returns 40 作为应该吗?
Link: http://jsfiddle.net/u8y8zh72/3/
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<style>
footer {
height: 75px;
position: fixed;
bottom: 0;
}
</style>
</head>
<body>
<div class="container">
<ul id="js-news" class="js-hidden"></ul>
</div>
<footer>
<div class="container" id="newswiretxt">
<span></span>
</div>
</footer>
</body>
<script type="text/javascript">
var newsWire = [];
function loadNewswire() {
$.getJSON('http://api.nytimes.com/svc/news/v3/content/all/all.json',
{'api-key': 'XXXXXXXXX'},
function(data) {
console.log(data)
var newsWireTemp = [];
for (var i = 0; i < data.results.length; i++) {
var breakingNews = data.results[i];
var breakingTitle = breakingNews.title;
var breakingAbstract = breakingNews.abstract;
newsWireTemp.push(breakingTitle);
newsWireTemp.push(breakingAbstract);
}
newsWire = newsWireTemp;
console.log(newsWire.length);
});
}
loadNewswire();
console.log(newsWire.length);
$(document).ready(function() {
var items = newsWire;
$text = $('#newswiretxt span'),
delay = 10; //seconds
function loop (delay) {
$.each(items, function (i, elm){
$text.delay(delay*1E3).fadeOut();
$text.queue(function(){
$text.html(items[i]);
$text.dequeue();
});
$text.fadeIn();
$text.queue(function(){
if (i == items.length -1) {
loop(delay);
}
$text.dequeue();
});
});
}
loop(delay);
});
</script>
主要是这个:
...
loadNewswire();
console.log(newsWire.length);
...
当您调用 loadNewsWire
时,您正在启动一个异步 JSON 请求。但是,脚本执行不会等待该函数完成,因此它会立即运行以下 console.log
语句。那时,JSON 请求还没有完成,所以 newsWire
数组仍然是空的——这就是为什么 console.log(newsWire.length)
returns 0 在那里。
在您的 loadNewsWire
函数中,您有一个回调函数,该函数会在 JSON 请求已 return 编辑了您的数据时执行。此时您正在填充数组,console.log(newsWire.length)
为您提供预期的计数。
更新回复评论:
Is there anyway to make the rest of my code wait for the function to execute?
是的! $.getJSON
是 $.ajax
的便利包装器,它 return 是一个 jqXHR
对象(jQuery documentation 中有完整有趣的细节)。您可以向该对象添加额外的回调,这就是您在对 $.getJSON
的调用中实际执行的内联操作。以下:
$.getJSON('http://...', { 'api-key': '...' },
function (data) {
// stuff
});
相当于:
$.getJSON('http://...', { 'api-key': '...' })
.done(function (data) {
// stuff
});
因此,如果您将 loadNewswire
修改为 return 从 $.getJSON
编辑的对象 return,您可以为其附加一个回调,等待异步操作完成,并将其余代码放入其中。如果您将代码更改为:
function loadNewswire() {
return $.getJSON(
...
);
};
然后您可以使用 done
、fail
或 always
回调之一包装您要等待的代码。
您的调用代码将如下所示:
loadNewswire().done(function () {
console.log(newsWire.length);
// and any other code you want to hold until the async operation is complete
});
我建议通读 previously mentioned documentation - 它有点沉重,但它很好地概述了如何使用 jQuery.
处理异步请求