繁体   English   中英

等待函数完成,然后再继续执行$ .each函数中的下一个循环

[英]wait for the function to finish before continuing to the next loop in a $.each function

无论如何,我都不是JS或jQuery的专家。 我正在尝试为执行如下操作的聊天应用编写代码:

  • 从AJAX通话中获取对话列表
  • 用API返回的对话填充网页的左窗格
  • 在左侧窗格中填充所有对话后,将聊天列表项绑定到该窗格的右侧。

现在我遇到的问题是这个。 从API调用获取对话列表后,我遍历该列表并将每个项目绑定到窗格。 .each函数在绑定函数执行完代码块之前转到下一个迭代。 当具有$ .each迭代器的函数执行完后,我使用“ .done()”填充第一个对话项的聊天记录。但是由于循环在所有对话都未正确绑定之前完成,因此聊天列表是因此,我无法看到任何对话,因此无法填充任何事件。

我要达到的目的是等待绑定对话完成执行,然后继续进行迭代。

我的代码如下:

function (data) {
                    $.each(data, function (index, value) {

                        if (value.toUser == loggeduser) {
                            var isMe = false;
                            getUser(value.fromUserID, function (user) {
                                if (user.picturename == 'none') {
                                    bindConversationItem(value.chatMessages[0].message, user.username, 'nopic.png', value.conversationID);
                                }
                                else {
                                    bindConversationItem(value.chatMessages[0].message, user.username, user.picturename, value.conversationID);
                                }
                            });
                        }
                        else {
                            getUser(value.toUserID, function (user) {
                                var isMe = true;
                                if (user.picturename == 'none') {
                                    bindConversationItem(value.chatMessages[0].message, user.username, 'nopic.png', value.conversationID);
                                }
                                else {
                                    bindConversationItem(value.chatMessages[0].message, user.username, user.picturename, value.conversationID);
                                }

                            });
                        }
                    });
                }).done(function (data) {
                    populateFirstConversation(data);
                    bindEvents();

                });

这是我的bindConversationItem函数

   function bindConversationItem(message, username, userimage, index) {
            var conv_item = '<li> <a href="#" conversation-index = '+index+' class="clearfix">'
                            + '<img src="http://localhost:1995/contents/member/' + userimage + '" alt="" class="img-circle">'
                            + '<div class="friend-name">'
                                + '<strong>' + username + '</strong>'
                            + '</div>'
                            + '<div class="last-message text-muted">' + message + '</div>'
                            + '<small class="time text-muted">Just now</small>'
                            + '<small class="chat-alert label label-danger">1</small>'
                        + '</a>'
                    + '</li>'


            $("ul.friend-list").append(conv_item);
        }

我尝试将代码包装在一个函数中并使用一个回调函数,但似乎无法正常工作。 这里的任何解决方案表示赞赏。

编辑

对于每个循环,我都有一个异步的函数“ getUser”。它看起来像这样:

            function getUser(userid, callback) {
            $.ajax({
                url: 'http://localhost:1995//api/member/' + userid
            }).done(callback)
        }

最好的解决方案当然是使用promises ,但是正如您所报告的那样,您对这种语言不是很了解,这种解决方案对您的原始代码影响不大:

而是$ .each循环,一次执行每个迭代,然后在回调触发时调用下一个。

function (data) {
    function done() {
        populateFirstConversation(data);
        bindEvents();
    }

    function getNextConversation(index) {
        if (index == data.length)
            return done();

        var value = data[index];

        if (value.toUser == ...) {
            getUser(..., function () {
                ...

                getNextConversation(index + 1);
            });
        } else {
           getUser(..., function () {
                ...

                getNextConversation(index + 1);
           });
        }
    }

    getNextConversation(0);
}

您可以使用.queue()$.map().promise()按顺序返回异步调用的结果,并在queueName所有函数完成后执行任务

 function processQueue (data) { return $({}).queue("ajax", $.map(data, function(id) { return function(next) { return getUser(id, function(val) { // do stuff when asynchronous function returns a value return $("<div>", {html:"id:" + id + ", value:" + val * Math.PI}) .appendTo("body").after("<br>"); }, next) // pass `next` function } })).dequeue("ajax").promise("ajax") } function getUser(value, callback, next) { // do asynchronous stuff, eg, `$.ajax()` return new $.Deferred(function(dfd) { setTimeout(function() { dfd.resolve(value * 10) }, Math.floor(Math.random() * 1500)) }) // chain `.then()` which calls `callback`, and `.then()` // which call next function in `"ajax"` queue .then(callback).then(next) } var arr = [1, 2, 3, 4, 5]; var queue = processQueue(arr); // do stuff when queue completes queue.then(function(data) { console.log("complete") }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> </script> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM