JavaScript Promise.all 代码未按预期工作

标签 javascript arrays dictionary promise

<分区>

我有以下代码从 mySQL 数据库中获取信息。 数据库包括几个表,其中有一个 Activity 表,有一个 channelId 字段,一个 Channel 表有一个 userId 字段,还有一个 User 表有一个用户名字段。 函数 getAllProjectACtivities(user,project) 返回 Activity 对象数组的 promise ,每个对象都包含所有 Activity 表字段。 函数 findChannel(channelId) 返回单个 Channel 对象的 promise ,包括所有 Channel 表字段。 findUser(userId) 函数返回单个 User 对象的 promise ,包括所有 User 表字段。 所有 3 个函数都隐藏了对数据库的 JSON Ajax 请求,并且已经过测试可以独立正常工作。

我在这里尝试做的是获取事件列表,为每个事件获取 channel ,为每个 channel 获取用户。 然后我构建了一个包含 2 个事件字段和一个用户字段的事件表。

为此,我需要生成对象数组的 3 阶段数据库访问。下面是代码:

$(document).ready(function(){    
    var projNum=1;
    var userNum=1;
    var globalActivityList; //this global array will store data from the beginning of the promise chain to be used at the end of the chain
    $('#tableContainer').append('<table border="0" style="background-color: lightblue;"></table>');
    var table = $('#tableContainer').children();
//here goes:
    getUserProjectActivities(userNum,projNum)
        .then(function (activityList){
            table.append("<tr><th>Number</th><th>Description</th><th>Employee</th></tr>");
            globalActivityList=activityList;
            return Promise.all(activityList.map(function(activity){
                //alert(activity.activityChannelId);//******** shows the right stuff
                findChannel(activity.activityChannelId);
            }));
        })
        .then(function (channelList){
            alert (channelList.length);//******* gives the right size
            alert (channelList);//******** u-oh, this shows ,,,,,,,,,,,, - the array is empty.<<<<<<<<<<<<<<<Problem
            return Promise.all(channelList.map(function(channel){
                findUser(channel.channelEmployeeId);
            }));
        })
        .then(function(userList){
            for (var i=0; i<userList.length; i++){
                var tableString="<tr>";
                tableString+="<td>"+globalActivityList[i].activitityId+"</td>";
                tableString+="<td>"+globalActivityList[i].activitityDescription+"</td>";
                tableString+="<td>"+userList[i].userName+"</td>";
                tableString+="</tr>";
                table.append(tableString);
            }
        })
});

发生的是第二个 .then 得到一个没有信息的数组,当然所有后续代码都会失败。 任何想法?谢谢。

最佳答案

这些回调需要返回一个 promise ,因为它们是异步的。您的 map 调用当前会生成一个 undefined 数组,这些数组将被馈送到 Promise.all 中。必须是

return Promise.all(activityList.map(function(activity){
    return findChannel(activity.activityChannelId);
//  ^^^^^^
}));

return Promise.all(channelList.map(function(channel){
    return findUser(channel.channelEmployeeId);
//  ^^^^^^
}));

请注意,您的 globalActivityList 是一种反模式。如果为每个事件创建一个包含 channel 和用户的对象会更好,这样所有这些对象的列表就成为一个单一 promise 的结果——无需离开链:

getUserProjectActivities(userNum, projNum)
  .then(function(activityList) {
      table.append("<tr><th>Number</th><th>Description</th><th>Employee</th></tr>");
      return Promise.all(activityList.map(function(activity) 
          return findChannel(activity.activityChannelId);
            .then(function(channel) {
                return findUser(channel.channelEmployeeId);
            })
            .then(function(user) {
                // maybe unnecessary intermediate object
                return {activity:activity.activityID, description:activity.activityDescription, user:user.userName};
            })
            .then(function(item) {
                var tableString="<tr>";
                tableString+="<td>"+item.activitity+"</td>";
                tableString+="<td>"+item.description+"</td>";
                tableString+="<td>"+item.user+"</td>";
                tableString+="</tr>";
                return tableString;
            });
      }));
  })
  .then(function (list) {
      for (var i=0; i<list.length; i++){
          table.append(list[i]);
      }
  });

关于JavaScript Promise.all 代码未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26316291/

相关文章:

javascript - 来自 webstorage 执行功能的复选框值

javascript - 如何在重定向到新 View 之前在 Controller 中创建警报提示?

javascript - 使用 jquery 计算价格和 TVA

javascript - 单击按钮元素时如何更新属性?

python - 多维python字典

c - 使用 C 中的排序字典对字符串进行拼写检查

javascript - Vue 2 - v-for 循环对象数组给出不同的结果

php - 如何组合两个数组而不重复值?

arrays - NodeJS - 使用 Q 对对象数组执行异步操作,但有所不同

java - 如何访问 map 中嵌套 map 中的项目 (Java)