【问题标题】:Promise.all([...]) filling in objectPromise.all([...]) 填充对象
【发布时间】:2018-06-13 03:43:13
【问题描述】:

我有一个带有一些 id 的对象,我需要通过在不同的端点获取来替换它们的关联对象。

{
  user: 123456
  items: [
    1234,
    4321,
  ]
}

我想获取它,其中 a 是 userId 的端点 GET /user 和每个项目 id 的 GET /item 。我希望返回一个完整的对象,例如:

{
  user: { ... }
  items: [
    { ... } 
    { ... } 
  ]
}

我所有的用户和项目功能都工作并且正在使用异步获取,所以我想我想要一些类似的东西:

const fillIn = async data => {
  return Promise.all(
    data.map(async obj => {
      const userId = obj.userId;
      const itemIds = obj.items
      return Promise.all([
        getUser(creatorId),
        Promise.all(itemIds.map(item => getItem(item)))
      ]);
    })
  );
};

我的问题是 promise.all 返回什么,什么时候返回?我不断得到未解决的函数,但我认为它的全部意义在于解决所有的承诺!?

【问题讨论】:

  • 请显示完整代码,包括datagetUser / getItem
  • Promise.all 返回一个承诺。您可以从中调用.then() 和其他promise 方法
  • 如果你试图使异步代码同步(我认为你是),这是不可能的。你必须要么await 它要么使用.then()
  • promise.all 只是一个promise,当所有promise 都从您输入的promise 数组中解决时,它就会被解决。将其视为包装其他 Promise 的 Promise,同时使用 async await 语法意味着您必须在所有异步调用上使用 await。就像其他人在这里说的那样
  • 我错过了“它什么时候返回?”的问题。答案是立竿见影。 Promise.all() resolves 在您传递给Promise.all() 的数组中列出的每个 promise 解析后立即返回的promise,并在any后立即拒绝> 在拒绝中传递的承诺。您可以使用Promise.all([...]).then(responses => {/* success/resolved */ }, err => { /* error/rejected */}) 处理这些问题

标签: javascript promise


【解决方案1】:

您需要的函数返回一个通过“填充”对象实现的承诺。这个promise实际上是一个promise的组合:一个用于用户,一个数组用于items中的每个项目......

function fillIn(object) {
    let filledInObject = { user:null, items:[] };
    let promises = object.items.map(i => {
        return getItem(i).then(item => filledInObject.items.push(item));
    });
    let userPromise = getUser(object.user).then(user => {
        filledInObject.user = user;
    });
    promises.push(userPromise);
    return Promise.all(promises);
}

还可以想象一个更通用的解决方案,其中属性名称映射到某个配置对象中的 getter:

// getUser and getItem are assumed as above
// add a plural form for getItems
// our getters will be indexed like this: { user:getUser, items:getItems }

function getItems(array) {
    let promises = array.map(i => getItem(i));
    return Promise.all(promises);
}

现在,一个通用的填充内...

function fillIn(object, getters) {
    let filledInObject = {};
    let promises = Object.keys(object).map(key => {
        let getter = getters[key];    // lookup a promise-returning function for the key
        // call it with the param in the object, use the result to fill-in the target object
        return getter(object[key]).then(result => {
            filledInObject[key] = result;
        });
    });
    return Promise.all(promises);
}

这样称呼它:

const getters = { user:getUser, items:getItems }
let opObject = { user: 123456, items: [ 1234, 4321 ] };

fillIn(opObject, getters).then(filledInObject => {
    console.log(filledInObject);
})

【讨论】:

    猜你喜欢
    • 2018-11-20
    • 2014-04-12
    • 2015-03-13
    • 2019-08-20
    • 2013-03-10
    • 1970-01-01
    • 2020-06-18
    • 1970-01-01
    相关资源
    最近更新 更多