简体   繁体   English

Promise.all 返回 Promise,而不是预期的数据有效载荷 in.next(...)

[英]Promise.all returning Promise, not the expected data payload in .next(…)

I am currently trying to understand Promises and Promise all.我目前正在尝试全部了解 Promises 和 Promise。 I have an implementation of what I want to achieve here that almost works:我有一个我想在这里实现的实现,几乎可以工作:

https://codepen.io/c0un7z3r0/pen/GRpPyar https://codepen.io/c0un7z3r0/pen/GRpPyar

The code is:代码是:

const currencyArray = [
  {
    currencyFrom: "USD",
    currencyTo: "GBP",
    urls:[
      "https://jsonplaceholder.typicode.com/todos/1",
      "https://jsonplaceholder.typicode.com/todos/2",
    ]
  },
  {
    currencyFrom: "SGD",
    currencyTo: "USD",
    urls:[
      "https://jsonplaceholder.typicode.com/todos/3",
      "https://jsonplaceholder.typicode.com/todos/4",
    ]
  },
  {
    currencyFrom: "CNY",
    currencyTo: "EUR",
    urls:[
      "https://jsonplaceholder.typicode.com/todos/5",
      "https://jsonplaceholder.typicode.com/todos/6",
    ]
  }
]

async function fetchData(currencyFrom, currencyTo, url) {
  const res = await fetch(url)
  let dataResp = await res.json()
  dataResp = dataResp.map((data) => data)
  let newDataObj = {
    currencyFrom: currencyFrom,
    currencyTo: currencyTo,
    response: dataResp,
  }
  return newDataObj
}

const promises = currencyArray.map((currency) =>
                                   currency.urls.map((url) => {
  return fetchData(currency.currencyFrom, currency.currencyTo, url).then(
    (data) => {
      // console.log(data)
      return data
    })
  })
)

Promise.all(promises)
  .then((data) => data)
  .then((data) => console.log('I expect data, but all I get is Promises, Promises:', data))

What I want to acheive is to map through each object in the currencyArray, fetch the data from each url in the currencyArray.url array then return a similar object for each of the currencyArray items when all of the promises have resolved, like so: What I want to acheive is to map through each object in the currencyArray, fetch the data from each url in the currencyArray.url array then return a similar object for each of the currencyArray items when all of the promises have resolved, like so:

[{
    currencyFrom: "USD",
    currencyTo: "GBP",
    responses:[
        // ** DATA FETCHED FROM API CALLS **
    ]

},{
    // ....more objects like the above
}
]

The codepen implementation above get 99% of the way there however no matter what I seem to do, the result always returns [Promise, Promise] array.上面的 codepen 实现完成了 99% 的工作,但是无论我做什么,结果总是返回 [Promise, Promise] 数组。 If I drill down into the array in the browser console I can actually see the resolved data however trying to access this information in.then() has proven fruitless.如果我在浏览器控制台中深入研究该数组,我实际上可以看到已解析的数据,但是尝试在.then() 中访问此信息已被证明是徒劳的。 Can anybody help me understand what I am doing wrong and possibly provide a working example?任何人都可以帮助我理解我做错了什么并可能提供一个可行的例子吗?

I've scoured stack overflow and tried many alternative implementations and the above is the closest to a working solution I have managed.我已经搜索了堆栈溢出并尝试了许多替代实现,以上是我管理过的最接近工作解决方案的解决方案。 Thanks in advance for any help you can provide.提前感谢您提供的任何帮助。

NOTE: For completeness, here is the actual implementation I have in my application ( https://codepen.io/c0un7z3r0/pen/ExVGQdK ), the codepen above is a stubbed in version modified to use a public API.注意:为了完整起见,这里是我在应用程序中的实际实现( https://codepen.io/c0un7z3r0/pen/ExVGQdK ),上面的代码笔是修改为使用公共 API 的版本。

The problem doesn't seem to be in the promises themselves, but in the way the array is built.问题似乎不在于承诺本身,而在于构建数组的方式。 The inner map creates an inner collection of promises, but the outer map does not use those promises directly.内部 map 创建了一个内部承诺集合,但外部 map 不直接使用这些承诺。 flatMap can be used to flatten the collection: flatMap可用于展平集合:

const promises = currencyArray.flatMap(currency =>
  currency.urls.map(url => fetchData(currency.currencyFrom, currency.currencyTo, url))
  );

 const currencyArray = [ { currencyFrom: "USD", currencyTo: "GBP", urls:[ "https://jsonplaceholder.typicode.com/todos/1", "https://jsonplaceholder.typicode.com/todos/2", ] }, { currencyFrom: "SGD", currencyTo: "USD", urls:[ "https://jsonplaceholder.typicode.com/todos/3", "https://jsonplaceholder.typicode.com/todos/4", ] }, { currencyFrom: "CNY", currencyTo: "EUR", urls:[ "https://jsonplaceholder.typicode.com/todos/5", "https://jsonplaceholder.typicode.com/todos/6", ] } ] async function fetchData(currencyFrom, currencyTo, url) { const res = await fetch(url), dataResp = await res.json(), newDataObj = { currencyFrom: currencyFrom, currencyTo: currencyTo, response: dataResp, }; return newDataObj } const promises = currencyArray.flatMap(currency => currency.urls.map(url => fetchData(currency.currencyFrom, currency.currencyTo, url)) ); Promise.all(promises).then(console.log);

Promise.all works when you have an array of promises [Promise, Promise, ...] . Promise.all在您有一系列承诺时[Promise, Promise, ...] In your case this is array of array of Promises [[Promise, Promise], ...]在您的情况下,这是一组 Promises [[Promise, Promise], ...]

This is how I would merge all those values这就是我合并所有这些值的方式

 const promises = [ [ new Promise((resolve, reject) => resolve({prop:1})), new Promise((resolve, reject) => resolve({prop:2})) ], [ new Promise((resolve, reject) => resolve({prop:3})), new Promise((resolve, reject) => resolve({prop:4})) ], [ new Promise((resolve, reject) => resolve({prop:5})), new Promise((resolve, reject) => resolve({prop:6})) ] ]; (async() => { const result = await Promise.all(promises.map(async pr => await Promise.all(pr))) console.log(result); })()

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

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