【问题标题】:Filtering and array of Objects which contains promises in Javascript过滤和包含 Javascript 中的承诺的对象数组
【发布时间】:2018-05-05 18:27:16
【问题描述】:

我有一个包含值列表的数组,其中一些是需要解决的承诺。

allGlobalFilters": [
    {
      "id": 503,
      "pubId": 18,
      "type": 15,
      "value": "{ \"adsize\":  [\"638x335\" , \"400x300\" , \"300x1050\", \"320x100\", \"640x480\" , \"700x392\",  \"360x480\", \"896x502\", \"960x538\", \"1024x573\", \"1088x609\"]}",
      "status": 4,
      "createTs": null,
      "updateTs": null,
      "createUser": "MMM",
      "updateUser": null,
      "percentage": 100,
      "rtbSspPublishers": { // the promise part 
        "id": 18,
        "name": "Mobile Nations\r\n",
        "domain": "http://www.mobilenations.com",
        "extPublisherId": 17
      }
    },
    {
      "id": 505,
      "pubId": 19,
      "type": 15,
      "value": "{ \"adPlatformType\": [\"APP\"] }",
      "status": 4,
      "createTs": null,
      "updateTs": null,
      "createUser": null,
      "updateUser": null,
      "percentage": 0,
      "rtbSspPublishers": { // the promise part
        "id": 19,
        "name": "Tom's Guide",
        "domain": "www.tomsguide.com",
        "extPublisherId": 17
      }
    },
    {
      "id": 514,
      "pubId": 19,
      "type": 15,
      "value": "{ \"adPlatformType\": [\"WEB\"] }",
      "status": 4,
      "createTs": null,
      "updateTs": null,
      "createUser": null,
      "updateUser": null,
      "percentage": 100,
      "rtbSspPublishers": { // the promise part
        "id": 19,
        "name": "Tom's Guide",
        "domain": "www.tomsguide.com",
        "extPublisherId": 17
      }
    },
    {
      "id": 516,
      "pubId": 19,
      "type": 15,
      "value": "{\"adPlatformType\": [\"MOBILE_WEB\"]}",
      "status": 4,
      "createTs": null,
      "updateTs": null,
      "createUser": null,
      "updateUser": null,
      "percentage": 100,
      "rtbSspPublishers": { // the promise part
        "id": 19,
        "name": "Tom's Guide",
        "domain": "www.tomsguide.com",
        "extPublisherId": 17
      }
    }
  ]

现在我需要在 promise 的条件下过滤这个数组,我该怎么做。

这是我尝试过的。

 data.filter(d => d.rtbSspPublishers.get().then(res => res.name.includes('Mobile')));

但这似乎不起作用。如何让异步值与数组过滤器一起使用?

【问题讨论】:

  • 您无法对异步数据进行同步过滤 - 您需要先等待 promise 解决,然后运行过滤器
  • @JaromandaX 我如何在这里等待同样的事情,我知道承诺是异步的,过滤器是同步的。谢谢你能不能给点提示
  • bluebird 有一个叫做 Promise.props 的东西,可能是你想要的
  • 这可能会有所帮助:stackoverflow.com/questions/33073509/promise-all-then-resolve,但不确定
  • 您的代码是 rtbSspPublishers.get().then 的事实...表明 rtbSspPublishers 不是 Promise,而是带有返回 Promise 的 .get 方法的某个对象,这可能使其成为稍微复杂一点

标签: javascript arrays


【解决方案1】:

一个更通用的答案...

使用我之前准备的简单“助手”

promiseProps = obj => {
    const keys = Object.keys(obj);
    return Promise.all(Object.values(obj)).then(results => Object.assign({}, ...results.map((result, index) => ({[keys[index]]: result}))));
};

你会简单

Promise.all(allGlobalFilters.map(obj => promiseProps(obj)))
.then(result => result.filter(({rtbSspPublishers}) => rtbSspPublishers.name.includes('Mobile'))
.then(filteredResult => {
    // filteredResult is your allGlobalFilters with promises resolved
    // filtered to include only the required items
    console.log(filteredResult );
});

无论有多少(第一级)属性是 Promise,这都会起作用

【讨论】:

  • 知道我们如何过滤
  • 过滤结果为.then
  • 它仍然是一个承诺 :(
  • 导致console.log(result); ?是承诺吗?
【解决方案2】:

只需将 Promise 映射到 Promise all 中的一个数组,等待它们解决,然后将它们映射回一个新数组。您可以覆盖旧数组或只保留对新数组的引用。

let allGlobalFilters = [{
  "id": 503,
  "pubId": 18,
  "type": 15,
  "status": 4,
  "createTs": null,
  "updateTs": null,
  "createUser": "MMM",
  "updateUser": null,
  "percentage": 100,
  "rtbSspPublishers": Promise.resolve({
    "id": 18,
    "name": "Mobile Nations",
    "domain": "http://www.mobilenations.com",
    "extPublisherId": 17
  })
}]

Promise.all(allGlobalFilters.map(({rtbSspPublishers}) => rtbSspPublishers)).then(values => {
  const theNewValues = allGlobalFilters
                      .map((item, i) => ({...item, rtbSspPublishers: values[i]}))
                      .filter(item => item.rtbSspPublishers.name.startsWith('Mobile'))
  })

不扩散对象的更新

Promise.all(allGlobalFilters.map(({rtbSspPublishers}) => rtbSspPublishers)).then(values => {
  const theNewValues = allGlobalFilters
                      .map((item, i) => { return  Object.assign({}, item, { rtbSspPublishers: values[i] }) })
                      .filter(item => item.rtbSspPublishers.name.startsWith('Mobile'))
    // use theNewValues right here, or call a methof
    // someMethod(theNewValues);
  })

【讨论】:

  • const theNewValues = 改成allGlobalFilters =
  • @INFOSYS 要在 allGlobalFilters 上运行,您必须在代码的 .then 部分中执行此操作。如果您在then 之前或之后执行此操作,则不会更新数组。所以请在then 部分进行任何额外的调用或更新
  • 你没有任何 babel 预设?好吧,我更新它以不使用对象上的传播。
  • 如果你做对了它不应该,我在一个 repl 上测试了它并且它有效。您必须将其余代码放入.then 部分。我添加了一些 cmets 用于添加代码的位置。
猜你喜欢
  • 1970-01-01
  • 2019-07-30
  • 2017-01-28
  • 2021-08-28
  • 2019-10-01
  • 2022-08-15
  • 1970-01-01
  • 1970-01-01
  • 2020-09-22
相关资源
最近更新 更多