另一个函数完成JavaScript和JQuery之后运行函数

时间:2014-10-09 05:49:41

标签: javascript jquery function

我需要一些帮助。我正在尝试运行我的第二个函数“likeLinks();”但只有在我的第一个函数“getLikeURLs();”之后完了。这是因为我的第二个函数依赖于链接Array来执行。看起来他们正试图同时运行。

任何帮助都将不胜感激。

    var links = [];
    var url = '/' + window.location.pathname.split('/')[1] + '/' + window.location.pathname.split('/')[2] + '/'
    getLikeURLs();
    likeLinks();

    function getLikeURLs() {
        for (i = 1; i < parseInt(document.getElementsByClassName('PageNav')[0].getAttribute('data-last')) + 2; i++) {
            var link = $.get(url + 'page-' + i, function(data) {
                //gets the like links from current page
                $(data).find('a[class="LikeLink item control like"]').each(function() {
                    links.push($(this).attr('href')); // Puts the links in the Array
                });
            });
        }
    }

    function likeLinks() {
        for (t = 0; t <= links.length; t++) {
            var token = document.getElementsByName('_xfToken')[0].getAttribute('value')
            $.post(links[t], {
                _xfToken: token,
                _xfNoRedirect: 1,
                _xfResponseType: 'json'
            }, function(data) {});
        }
    }

2 个答案:

答案 0 :(得分:1)

link变量实际上是jQuery deferred objects - 将它们存储在一个数组中,然后你可以使用$.when()来创建一个仅在以前所有{{1}时解析的新延迟对象操作已完成:

$.get()

然后,开始功能链:

function getLikeURLs(url) {     // NB: parameter, not global
    var defs = [], links = [];  // NB: links no longer global

    for (...) {
        var link = $.get(...);
        defs.push(link);
    }

    // wait for previous `$.get` to finish, and when they have create a new
    // deferred object that will return the entire array of links
    return $.when.apply($, defs).then(function() { return links; });
}

请注意,getLikeURLs(url).then(likeLinks); 现在将传递链接数组,而不是从全局状态访问它。该函数也应该被重写,以便您等待其likeLinks调用完成:

$.post

P.S。不要在function likeLinks(links) { // loop invariant - take it outside the loop var token = document.getElementsByName('_xfToken')[0].getAttribute('value'); // create array of deferreds, one for each link var defs = links.map(function(link) { return $.post(link, { _xfToken: token, _xfNoRedirect: 1, _xfResponseType: 'json' }); }); // and another for when they're all done return $.when.apply($, defs); } 语句中放置那个(相对)昂贵的parseInt(document.getAttribute(...))表达式 - 它会导致每次迭代都对它进行评估。在循环外部计算一次并将其存储在变量中。还有一些其他地方您不必要地重复拨打电话,例如: for

答案 1 :(得分:0)

编辑:我的回答讨论了这个问题,但请参阅Alnitak回答更好的解决方案。

get in getLikeURLs和putLinks中的get都是异步的。对这两个函数的调用立即返回。当在稍后的某个不确定时间从被调用服务器返回数据时,然后调用回调函数。看跌期权可能会在收益之前返回,这将是您的案例中的问题。另请注意,JavaScript不是多线程的,因此getLikeURL和likeLinks这两种方法永远不会同时运行。另一方面,回调函数可能在以后的任何时候被调用,而不能保证回调订单。例如,第3次获取/放置可能会在第1次获取/放入循环之前返回。

你可以使用$ .ajax来指定获取和放置是同步的,但这是不明智的,因为如果任何get / put没有在合理的时间内返回(例如服务器离线),浏览器将挂起)。另外,你没有“多任务处理”#34;发送大量请求并使各种服务器同时工作的好处。他们会连续这样做。

诀窍是简单地在getLikeURL中调用likeLinks作为回调函数。因为for循环你的情况有点棘手,但这应该有效:

var links = [];
    var url = '/' + window.location.pathname.split('/')[1] + '/' + window.location.pathname.split('/')[2] + '/'
    getLikeURLs();
    //likeLinks();  // Don't call yet.  Wait for gets to all return.

    function getLikeURLs() {
        var returnCount = 0;   // Initialize a callback counter.
        var count = parseInt(document.getElementsByClassName('PageNav')[0].getAttribute('data-last')) + 1;
        for (i = 0; i < count; i++) {
            var link = $.get(url + 'page-' + (i + 1), function(data) {
                //gets the like links from current page
                $(data).find('a[class="LikeLink item control like"]').each(function() {
                    links.push($(this).attr('href')); // Puts the links in the Array
                });

                // If all gets have returned, call likeLinks.
                returnCount++;
                if (returnCount === count) {
                   likeLinks();
                }
            });
        }
    }

    function likeLinks() {
        for (t = 0; t <= links.length; t++) {
            var token = document.getElementsByName('_xfToken')[0].getAttribute('value')
            $.post(links[t], {
                _xfToken: token,
                _xfNoRedirect: 1,
                _xfResponseType: 'json'
            }, function(data) {});
        }
    }