【问题标题】:Global array not updating after .push inside function [duplicate].push内部函数后全局数组未更新[重复]
【发布时间】:2016-02-10 06:48:49
【问题描述】:

大家好,谁能帮帮我? 基本上,我想制作一个突发新闻页脚,循环遍历 newsWire 数组并自动更新文本。问题是当我在 loadNewswire 函数之外运行 console.log(newsWire.length) 时,它返回 0,而里面的 console.log 返回 40?

链接: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); 在回调 (newsWire = newsWireTemp;) 之前运行。你可以看出,因为你 console.log(newsWire.length) 是在 console.log(newsWire.length); 之后输出的

标签: javascript arrays push global


【解决方案1】:

主要是这样的:

...
loadNewswire();
console.log(newsWire.length);
...

当您调用 loadNewsWire 时,您正在启动一个异步 JSON 请求。但是,脚本执行不会等待该函数完成,因此它会立即运行以下console.log 语句。此时,JSON 请求还没有完成,所以 newsWire 数组仍然是空的 - 这就是为什么 console.log(newsWire.length) 在那里返回 0。

在您的loadNewsWire 函数中,您有一个回调函数,该函数在 JSON 请求返回您的数据时执行。此时您正在填充数组,console.log(newsWire.length) 会为您提供预期的计数。


根据评论更新:

有没有办法让我的其余代码等待函数 执行?

是的! $.getJSON$.ajax 的便捷包装器,它返回一个 jqXHR 对象(jQuery documentation 中的完整详细信息)。您可以向该对象添加额外的回调,这就是您在调用$.getJSON 时实际内联的操作。以下:

$.getJSON('http://...', { 'api-key': '...' },
    function (data) {
        // stuff
    });

相当于:

$.getJSON('http://...', { 'api-key': '...' })
    .done(function (data) {
        // stuff
    });

因此,如果您修改您的loadNewswire 以返回从$.getJSON 返回的对象,您可以为其附加一个回调,该回调将等待异步操作完成,并将其余代码放入其中。如果您将代码更改为:

function loadNewswire() {
    return $.getJSON(
        ...
    );
};

然后您可以使用donefailalways 回调之一来包装您想要等待的代码。

您的调用代码将如下所示:

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 处理异步请求。

【讨论】:

  • 谢谢,这也是我的想法,因为我可以在控制台中看到数字出现的时间。有没有办法让我的其余代码等待函数执行?
  • @JeppeGelardiMadsen 为您的评论更新了答案。
猜你喜欢
  • 1970-01-01
  • 2016-12-24
  • 2017-01-15
  • 1970-01-01
  • 2012-12-12
  • 2019-06-08
  • 2017-08-07
  • 2019-02-10
相关资源
最近更新 更多