javascript - 在继续 $.each 函数中的下一个循环之前等待函数完成

标签 javascript jquery

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

  • 从 AJAX 调用中获取对话列表
  • 使用 API 返回的对话填充网页的左 Pane
  • 在左 Pane 填充所有对话后,将聊天列表项绑定(bind)到 Pane 的右侧。

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

我想要实现的是等待绑定(bind)对话完成执行,然后继续迭代。

我的代码如下:

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”,它在 for each 循环中是异步的。它看起来像这样:

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

最佳答案

您可以使用 .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, e.g., `$.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>

关于javascript - 在继续 $.each 函数中的下一个循环之前等待函数完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39552847/

相关文章:

php - 使用 PHP 和 jQuery 生成并下载 .csv 文件

javascript - 从本地存储中检查时清除检查的 li 元素

javascript - 使用 api 中用户输入返回的值

javascript - 我想使用 for 循环重复一个函数,但 for 循环什么也不做

javascript - polymer 1.4.0 至 1.7.0,全局 :root styles no longer work

javascript - jquery sortable 无法读取属性 'top'

javascript - 仅当使用 jquery 未正确输入用户名或密码时,如何才能显示错误消息?

javascript - 在一页上进行多个 imageLoaded 调用,并确保每个调用都已完成,然后再继续

javascript - 动态 JavaScript 驱动页面的 SEO

jquery - 按顺序显示子菜单项