如何在同步等待的同一函数中使用 fetch 和 fetch 的结果

Posted

技术标签:

【中文标题】如何在同步等待的同一函数中使用 fetch 和 fetch 的结果【英文标题】:How do i use fetch with a result from a fetch in the same function with sync await 【发布时间】:2021-10-26 01:46:18 【问题描述】:

promise 创建一个像这样的数组,取自控制台:

(6) [Promise, Promise, Promise, Promise, Promise, Promise]
0: Promise <fulfilled>: undefined
1: Promise <fulfilled>: undefined
2: Promise <fulfilled>: undefined
3: Promise <fulfilled>: undefined
4: Promise <rejected>: SyntaxError: Unexpected token < in JSON at position 0
5: Promise <fulfilled>: undefined
length: 6

无法使用。

代码是这样的:

export default async function getData() 
  let response = await request('http://localhost:2000/api/ves.json').then((data) => fetch(data));
  
  let store = await response.json();
  let list = await  store.map(async (input, index)=>
    let details = await request(`http://localhost:2000/api/$input.id.json`).then((data) => fetch(data));
   let foo = await details.json();
   console.log(foo);
    input = await ...input, ...foo;
  );
  
  return  list;

此时,返回列表(使用 useData 函数时)映射似乎还没有完成。所以它返回“promise”而不是它应该返回的列表。

目的是组合对象。这不是通过使用来自第一个对象(在对象数组中)的信息来从第二个对象获取信息。然后将第二个对象推入第一个对象,在数组中的同一点检索信息以获得第二个对象。

如果我也这样做,也会出现同样的问题

    input = await ...input, ...foo;
  );
  await Promise.all(list)
  return  list;

   console.log(foo);
    input = await ...input, ...foo;
  );
  let fish = await Promise.all(list)
  return  fish;

给出控制台错误

(6) [undefined, undefined, undefined, undefined, undefined, undefined]

这个useData函数是通过这个在react页面中调用的。

  const [ves] = useData();

      useEffect(()=>
    
        console.log(ves);
      ,[ves])

【问题讨论】:

await Promise.all(list) 应该等待映射数组中的所有 Promise。 替换“返回列表;” with let newList = await Promise.all(list) return newList;有同样的问题 【参考方案1】:

您没有在 .map 函数中返回任何内容。您还需要在.map 将返回的承诺数组上使用Promise.all()(因为您传递给它的函数是async,这意味着它将始终将返回包装在Promise 中。

另外,input = await ...input, ...foo; 对我来说真的没有意义。您等待承诺,而不是同步的值分配。

export default async function getData() 
  let response = await request('http://localhost:2000/api/ves.json').then((data) => fetch(data));

  let store = await response.json();
  let list = store.map(async(input, index) => 
    let details = await request(`http://localhost:2000/api/$input.id.json`).then((data) => fetch(data));
    let foo = await details.json();
    console.log(foo);
    // Have to return something within the .map
    return 
      ...input,
      ...foo
    ;
  );
  
  // Have to wait for all the mapped promises to resolve
  const resolvedList = await Promise.all(list);

  return resolvedList;

还有一个问题是您没有.catch 任何可能在提取期间发生的错误。我明白了

Promise &lt;rejected&gt;: SyntaxError: Unexpected token &lt; in JSON at position 0

这意味着其中一个 API 返回的是 html 而不是 JSON,这会导致 .json() 抛出。


Array.prototype.map() 是一种组合函数。它迭代一个数组,处理该数组的值,并返回一个与处理后的值相同大小的新数组。将其视为一种将值映射到另一个值的方式。

在您的示例中,您尝试将网络响应映射到其他网络请求。如果你不返回,则暗示“我不关心处理后的值”,此时你不妨使用.forEach

确实在意回复。因此,您应该在 map 函数中返回值(返回值是解析为数据的承诺),然后 Promise.all() 映射数组,以便它解包为实际数据数组。

【讨论】:

在等待的 Promise 之后是否有返回的原因或 return await Promise.all(list) 不起作用的原因? @DᴀʀᴛʜVᴀᴅᴇʀ 不,但我想让 OP 明白这一点。我认为简洁的语法可能是首先让他们绊倒的原因。 如评论编辑中所述,此建议不起作用,直接复制粘贴您所写的内容也不起作用。对不起,我仍然坚持这一点。在这个问题之前,我实际上已经尝试过 promise.all()。 @AlexanderHemming 是的,但是除了Promise.all 之外还有更多错误,比如实际上从.map 返回了一些东西,这是另一个错误。这就是为什么你有一个[undefined, undefined, undefined] 的数组。 @AlexanderHemming 添加了关于 .map() 的注释。

以上是关于如何在同步等待的同一函数中使用 fetch 和 fetch 的结果的主要内容,如果未能解决你的问题,请参考以下文章

fetch() 完成后如何调用函数

React如何使用内置的fetch模块

如何在异步函数中处理多个等待

如何同步编写fetch?

线程同步

如何在 fetch 中执行跨域请求以及异步等待? (CORS 错误)[重复]