简体   繁体   English

如何Promise.all对于嵌套数组?

[英]How to Promise.all for nested arrays?

Structure of the data: 数据结构:

tasks: [
  {
    name: "get milk",
    users: ["abc", "def"]
  },
  {
    name: "buy bread",
    users: ["def", "ghi"]
  }
]

I need to get the email address of each one of the users from the database (so far so good) and wait for all tasks to be completed, then move on and do something with the data. 我需要从数据库中获取每个用户的电子邮件地址(到目前为止非常好),并等待所有任务完成,然后继续进行数据处理。 The place where it doesn't work is written in the comments below: 无效的地方写在下面的注释中:

var tasks_with_emails = tasks.map(function(task) {
  var emails = task.users.map(function(user) {
    return user_to_email(user); // from the database
  });
  Promise.all(emails).then(function(emails) {
    task.emails = emails;
    console.log(task); // this one works fine
    return task;
  }).catch(next);
});
Promise.all(tasks_with_emails).then(function(tasks) {
  console.log(tasks); // <==== this one fires too quickly
}).catch(next);

So tasks_with_email should wait for all nested emails to resolve first, but it doesn't. 因此, tasks_with_email应该等待所有嵌套的emails首先解析,但不是。

Once you add the return in front of Promise.all() , your code works for me, as you can see in the below example. 一旦在Promise.all()前面添加了return,您的代码就对我Promise.all() ,如下面的示例所示。 So have a look at what user_to_email() returns. 因此,请查看user_to_email()返回的内容。 This should be a promise that resolves into the email string. 这应该是一个可以解析为电子邮件字符串的承诺。

 const user_to_email = user => new Promise(( resolve, reject ) => { setTimeout(() => resolve( `${ user }@example.com` ), 3000 ); }); const tasks = [ { name: "get milk", users: ["abc", "def"] }, { name: "buy bread", users: ["def", "ghi"] } ]; const tasks_with_emails = tasks.map( task => { const emails = task.users.map( user => { return user_to_email(user); // from the database }); return Promise.all(emails).then( emails => { task.emails = emails; return task; }); }); Promise.all(tasks_with_emails).then( tasks => { console.log(tasks); // <==== this one fires too quickly }); setTimeout(() => console.log( '1000ms' ), 1000 ); setTimeout(() => console.log( '2000ms' ), 2000 ); setTimeout(() => console.log( '2999ms' ), 2999 ); 

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

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