javascript - 数组对象循环javascript中的麻烦
问题描述
当我不想从 api 中获取我的数组对象时,我遇到了麻烦,当我运行 forEach 时,控制台不显示任何内容,我的代码和我的数组对象是这样的:
function renderingData(){
const ra = fetching()
console.log(typeof(ra))
console.log(ra)
ra.forEach( as => console.log(as))
}
renderingData()
数组中共有 224 个对象,我的 forEach 也不工作,这是我的获取函数:
function fetching() {
let result = []
fetch("the-url", {
"method": "GET",
"headers": {
"x-rapidapi-host": "the-host",
"x-rapidapi-key": "the-key"
}
})
.then(res => res.json())
.then(res => res.response.forEach( d => {
let ar = {
negara:d.country,
positif:d.cases.active,
sembuh:d.cases.recovered,
meninggal:d.deaths.total,
total:d.cases.total
}
result.push(ar)
}))
return result
}
但是当我尝试像这样测试写maual数组时:
function renderingData(){
// const ra = fetching()
const rr = [{negara: "China", positif: 723, sembuh: 77474, meninggal: 4633, total: 82830},
{negara: "Italy", positif: 105813, sembuh: 66624, meninggal: 26977, total: 199414},
{negara: "Spain", positif: 85069, sembuh: 120832, meninggal: 23521, total: 229422},
{negara: "Germany", positif: 37839, sembuh: 114500, meninggal: 6050, total: 158389}
]
console.log(typeof(rr))
console.log(rr)
rr.forEach( as => console.log(as))
}
renderingData()
解决方案
你误解了 Promises 的异步特性。别担心,它们很复杂。
如果我必须给你上面的 Sparknotes,你就不会再使用return
了。
让我们看看你的fetching
功能:
function fetching() {
let result = []
fetch("the-url", {
"method": "GET",
"headers": {
"x-rapidapi-host": "the-host",
"x-rapidapi-key": "the-key"
}
})
.then(res => res.json())
.then(res => res.response.forEach( d => {
let ar = {
negara:d.country,
positif:d.cases.active,
sembuh:d.cases.recovered,
meninggal:d.deaths.total,
total:d.cases.total
}
result.push(ar)
}))
return result
}
你发现了吗?
您正在混合同步和异步方法。在函数的顶部,您声明result
为一个空数组。之后,您开始获取。
return
不等待承诺完成,获取开始它自己的冒险,并且您的返回立即发生(在您的任何数据返回之前!)
这是发生的事情:
fetching called ----------> return result (empty array)
|
|
|
(eventually, some time later)
|
|
|
V
Promise fulfilled, data is sent back
或者,作为一个列表:
- 你的
fetching
函数被调用 - 您创建一个空的结果数组并开始提取
- 你返回你的空数组
- 一段时间后,数据又回来了。你错过了!
你可以做很多事情来解决这个问题。一种较旧的方法是使用回调。
function fetching(callback){
// After the forEach, but still in the .then:
if(callback) callback(result);
}
一些更好的方法是返回你的 OWN 承诺。您可以使用该new Promise()
对象。实现起来并不复杂。
当然,两者都需要你修改你的renderingData
函数。
最后,如果您不关心 Internet Explorer(我不关心!)您可以使用async
and await
,这是我的最爱。它使代码更具可读性。
研究所有这些替代品并使用您喜欢的任何一种!
async
这是一个使用and的简短示例await
,现代解决方案(同样,如果您尝试让它运行,Internet Explorer会感到不安)!
async function fetching(){
let result = []
let data = await (await fetch(url, options)).json();
data.forEach(...);
return data;
}
并使用获取功能:
let results = await fetching();
这就是我推荐 async 和 await 的原因!更简洁的代码,看!你仍然可以像普通函数一样使用 return !很好。
请注意,任何使用 await 的函数都需要标记为 async。这意味着您将需要更改:
async function renderingData
……还有
推荐阅读
- java - JavaFx KeyEvent on Rectangle doesn't work
- ios - 如何在 SwiftUI 的 ScrollView 中制作动画?SwiftUI 中的手风琴风格动画
- javascript - 如何修复“一个关闭按钮关闭所有模态”
- typescript - 为所有其他下拉菜单禁用一个下拉菜单的选定选项
- xamarin.android - 如何摆脱 Xamarin Android 上的这个资源 id 错误?
- javascript - 无服务器无法导入模块“处理程序”错误
- arduino - arduino 系统范围配置文件上的 Ardupilot 编译错误是“ArduPilot-Arduino-1.0.3-windows\hardware/tools/avr/etc/avrdude.conf”
- c++ - 在第二个监视器中显示图像的 C++ 列表屏幕
- c# - MailSystem.Net 有没有办法检查电子邮件的状态(是已读还是未读)?
- c# - 从winform中的子用户控件调用位于父用户控件中的函数