【问题标题】:How to aggregate data returned by 2 Promises in javascript如何在 javascript 中聚合 2 个 Promises 返回的数据
【发布时间】:2021-06-07 08:20:47
【问题描述】:

我在 js 文件中导入了 2 个承诺。 员工、经理 这两个承诺都包含作为 Json 对象数组的数据。 例如

employees = [ {"id": 1, "name": "Andrew", "age": 22}, {"id": 2, "name": "Eric", "age": 34}] 
managers = [ {"id": 1, "name": "Andrew", "department": "logistics"}, {"id": 2, "name": "Eric", "department": "sales"}]

我想根据 id 合并这些数据集并返回单个 Json 对象数组,如下所示-

empManager = [ {"id": 1, "name": "Andrew", "age" : 22, "department": "logistics"}, {"id": 2, "name": "Eric", "age": 34, "department": "sales"}]

我正在尝试使用 Promise 链接,但它不起作用

import {employees, managers} from './model';

export let empManager = function getData() {
    let employees;
    employees().then(emps => {
        employees = emps;
        return managers;
    }).then(mgrs => {
        return employees.map( e=> Object.assign(e, mgrs.find(m => m.id == e.id)))
    })
}

当我试图从 empManager 获取值时,如下所示,它给出了错误。

console.log(empManager())  // error - "mgrs.find is not a function".

我应该如何对 2 个 promise 的结果进行聚合?

【问题讨论】:

    标签: javascript promise


    【解决方案1】:

    您可以先使用Promise.all 解决这两个承诺。

    // Mimic async call.
    employees = () => new Promise(resolve => resolve([ {"id": 1, "name": "Andrew", "age": 22}, {"id": 2, "name": "Eric", "age": 34}]));
    managers = () => new Promise(resolve => resolve([ {"id": 1, "name": "Andrew", "department": "logistics"}, {"id": 2, "name": "Eric", "department": "sales"}]));
    
    // Wrap in async anonymous function to be able to use await.
    (async () => {
    
      // Use Promise.all to wait for both calls
      const [emps, mgrs] = await Promise.all([
        employees(),
        managers()
      ]);
    
      // Merge epmloyees
      const merged = {};
      emps
        .concat(mgrs)
        .forEach(u => {
          if(!(u.id in merged)) {
            merged[u.id] = {};
          }
          for(const key in u) {
            merged[u.id][key] = u[key];
          }
        })
      ;
    
      // Convert merged object into array again.
      console.log(Object.values(merged));
    
    })();
    

    【讨论】:

    • 非常感谢@Erik!使用 async 和 await 解决 Promise 有效!为了合并我做的数据如下。下面的 mergeData 再次是一个 Promise,其中包含来自两个 Promise 的合并数据。 export const mergeData = emps.map(e => Object.assign(e, mgrs.find(m => m.UserId == e.UserId)));
    • async/await 用异步污染了你的整个算法,并在开始时只有数据检索是异步的时将其与数据耦合。 empsmgrs 应该是您在 then IMO 中调用的函数的参数。该函数将只是一个可读的,但也是可重用的。
    • @geoffrey 你可能是对的。但是我不太关心这个例子,因为问题的答案归结为使用Promise.all
    • 当然。我不得不为其他读者解决这个问题。对直接使用await 访问值的痴迷使异步代码的表面积增大,并推迟了问题而不是解决问题。
    • @geoffrey true,谢谢您的补充。
    猜你喜欢
    • 1970-01-01
    • 2018-04-13
    • 2017-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-03
    • 2017-03-28
    相关资源
    最近更新 更多