如何仅在数据尚未加载时使用fetch



我有一个javascript函数,当单击button时触发。该函数从button元素中获取data-attribute,并将其用作从JSON数据集中查找值的键。

如果JSON数据已经从第一个按钮点击下载,我不想再下载数据集,因为没有理由这样做。

我试图通过声明一个空数组来做到这一点。然后找到数组的长度,如果长度为0,则获取JSON数据并将其推入数组。如果数组长度大于0,我知道我可以使用这个数据。

我不知道为什么,但每次我运行函数,数据被重新下载,不管条件语句。

我的代码

let arr = [[0,"Bulbasaur"],[1,"Ivysaur"],[2,"Venusaur"],[3,"Charmander"],[4,"Charmeleon"]]
let output = document.getElementById('output')
for (var key in arr) {
let button = document.createElement('button')
button.innerHTML = arr[key][1]
button.addEventListener('click',go)
button.setAttribute('data-key',arr[key][0])
output.append(button)
}
data = []
fetch("https://raw.githubusercontent.com/Biuni/PokemonGO-Pokedex/master/pokedex.json")
.then(response => {
return response.json();
})
.then(jsondata => data.push(jsondata))

function go() {

if (data.length > 0) {
fetch()
console.log('This data is new')
}

else {
console.log('This data is not new')
}


let key = this.dataset.key
document.getElementById('img').setAttribute('src',data[0].pokemon[key].img)
}
<img id="img" src=""/>
<div id="output"></div>

有人知道如何加载数据只有在必要的时候吗?

如果需要一些代码优化

为父div添加事件侦听器,而不是为每个新按钮添加一个事件这将减少事件侦听器的数量。

output.addEventListener('click', go);

使用DocumentFragment代替每次创建新按钮时更新DOM。

let fragment = new DocumentFragment();

将新创建的按钮添加到片段

fragment.appendChild(button);

最后,将创建的片段追加到目标元素#output

output.appendChild(fragment);

那么如何在go函数中获得按钮的数据集键?简单获取发生点击事件的目标元素,然后使用dataset获取其键。

let key = event.target.dataset.key;

下面的代码,如果数据长度为0。执行将等待API调用完成,因此await。要使用await,我们需要将其容器函数标记为async

let output = document.getElementById('output');
output.addEventListener('click', go);
let arr = [[0,"Bulbasaur"],[1,"Ivysaur"],[2,"Venusaur"],[3,"Charmander"],[4,"Charmeleon"]]

let fragment = new DocumentFragment();
for (var key in arr) {
let button = document.createElement('button')
button.innerHTML = arr[key][1]
//button.addEventListener('click',go)
button.setAttribute('data-key',arr[key][0]);
fragment.appendChild(button);
}
output.appendChild(fragment);
data = [];
async function go(event){
if(data.length==0) {
await fetch("https://raw.githubusercontent.com/Biuni/PokemonGO-Pokedex/master/pokedex.json")
.then(response => response.json())
.then(jsondata => data.push(jsondata)); 
}
// get dataset of the target element
let key = event.target.dataset.key;
document.getElementById('img').setAttribute('src',data[0].pokemon[key].img)
}
<img id="img" src=""/>
<div id="output"></div>

试试:

let arr = [[0,"Bulbasaur"],[1,"Ivysaur"],[2,"Venusaur"],[3,"Charmander"],[4,"Charmeleon"]]
let output = document.querySelector('#output')
for (let key in arr) {
let button = document.createElement('button')
button.innerHTML = arr[key][1]
button.addEventListener('click',go)
button.setAttribute('data-key',arr[key][0])
output.append(button)
}
data = []
async function go() {
if (data.length === 0) {
await fetch("https://raw.githubusercontent.com/Biuni/PokemonGO-Pokedex/master/pokedex.json")
.then(response => {
return response.json();
})
.then(jsondata => data.push(jsondata))
console.log('This data is new')
}
else {
console.log('This data is not new')
}
let key = this.dataset.key
document.querySelector('#img').setAttribute('src',data[0].pokemon[key].img)
}
<img id="img" src=""/>
<div id="output"></div>

你有你的条件,所以它做了一个空的取回,看起来很奇怪。我将其设置为对象并在其中一个对象函数中设置fetch并直接调用它-这也避免了全局命名空间的污染变量名如"data"或";arr"等。

var myObject = {
arr: [
[0, "Bulbasaur"],
[1, "Ivysaur"],
[2, "Venusaur"],
[3, "Charmander"],
[4, "Charmeleon"]
],
logMessage(message) {
console.log(message);
},
go: function() {
if (myObject.data.length <= 0) {
myObject.goGetem()
myObject.logMessage('This data is new');
} else {
myObject.logMessage('This data is not new');
}
let key = this.dataset.key;
document.getElementById('img').setAttribute('src', myObject.data[0].pokemon[key].img);
},
output: {},
data: [],
goGetem: function() {
myObject.logMessage('retreiving data');
fetch("https://raw.githubusercontent.com/Biuni/PokemonGO-Pokedex/master/pokedex.json")
.then(response => {
return response.json();
})
.then(jsondata => myObject.data.push(jsondata))
.then(function() {
myObject.logMessage('We fetched data: ' + !!myObject.data.length);
//use this to see what we got by uncommenting:
//myObject.logMessage(myObject.data);
});
},
setup: function() {
myObject.output = document.getElementById('output');
myObject.goGetem();
for (var key in myObject.arr) {
let button = document.createElement('button');
button.innerHTML = myObject.arr[key][1];
button.addEventListener('click', myObject.go);
button.setAttribute('data-key', myObject.arr[key][0]);
myObject.output.append(button);
};
}
};
myObject.setup();
<img id="img" src="" />
<div id="output"></div>

最新更新