Setinterval 函数重复 HTML 内容
Setinterval Function Repeating the HTML contents
我有一个 table 行内容是从 API 中获取的,而我使用 setinterval 函数只是重复更新的 table 行内容。
例如:(这是一个示例输出,不是实际的)
假设我有内容
John price 2000
在 1 秒的时间间隔后,它应该从 API 更新新值,例如
John price 2200
但我得到的是每次它刷新它只是添加像
John price 2000
John price 2200
John price 2120 ......
我的代码:
<table class="table">
<thead class="thead-dark">
<tr>
<th>Coin</th>
<th>Symbol</th>
<th>Currency</th>
<th>Price</th>
</tr>
</thead>
<tbody id="details">
<tbody>
</table>
var data, len, len1, name, symbol, currency, price;
const api_url = "https://api.wazirx.com/api/v2/market-status";
async function get_data_from_api() {
const response = await fetch(api_url);
data = await response.json();
len = Object.keys(data["markets"]).length;
len1 = Object.keys(data["assets"]).length;
for (let i = 0; i < len; i++) {
for (let j = 0; j < len1; j++) {
if (data['markets'][i]['baseMarket'] == data['assets'][j]['type'] && data['markets'][i]['quoteMarket'] == "inr") {
name = data['assets'][j]['name'];
symbol = data['assets'][j]['type'];
currency = data['markets'][i]['quoteMarket'];
price = data['markets'][i]['buy'];
document.getElementById('details').innerHTML += "<tr><td>" + name + "</td><td>" + symbol + "</td><td>" + currency + "</td><td>" + price + "</td></tr>";
}
}
}
}
get_data_from_api();
setInterval(get_data_from_api, 1000);
您只是将内容附加到节点
document.getElementById('details').innerHTML += "<tr><td>"+name+"</td><td>"+symbol+"</td><td>"+currency+"</td><td>"+price+"</td></tr>";
如果您有多个满足条件的节点,则必须在循环外将内容设置为空。
document.getElementById('details').innerHTML = "";
如果只有一个节点满足条件就直接赋值
document.getElementById('details').innerHTML = "<tr><td>"+name+"</td><td>"+symbol+"</td><td>"+currency+"</td><td>"+price+"</td></tr>";
工作解决方案将是这样的。
var data, len, len1, name, symbol, currency, price;
const api_url = "https://api.wazirx.com/api/v2/market-status";
async function get_data_from_api() {
const response = await fetch(api_url);
document.getElementById('details').innerHTML = '';
data = await response.json();
len = Object.keys(data["markets"]).length;
len1 = Object.keys(data["assets"]).length;
for (let i = 0; i < len; i++) {
for (let j = 0; j < len1; j++) {
if (data['markets'][i]['baseMarket'] == data['assets'][j]['type'] && data['markets'][i]['quoteMarket'] == "inr") {
name = data['assets'][j]['name'];
symbol = data['assets'][j]['type'];
currency = data['markets'][i]['quoteMarket'];
price = data['markets'][i]['buy'];
document.getElementById('details').innerHTML += "<tr><td>" + name + "</td><td>" + symbol + "</td><td>" + currency + "</td><td>" + price + "</td></tr>";
}
}
}
}
get_data_from_api();
setInterval(get_data_from_api, 1000);
您的代码不断添加到 table 的原因是因为您只添加了
document.getElementById('details').innerHTML += " ..... "
所以,当然这只会增加
天真的解决方案是在清除 innerHTML 的循环之前添加代码
document.getElementById('details').innerHTML = ""
一个更好的解决方案是在循环之前初始化一个字符串变量,添加到循环内的字符串,然后在循环之后一次更新innerHTML
const api_url = "https://api.wazirx.com/api/v2/market-status";
async function get_data_from_api() {
const response = await fetch(api_url);
const data = await response.json();
const len = Object.keys(data["markets"]).length;
const len1 = Object.keys(data["assets"]).length;
// this will hold the new HTML
let html = "";
for (let i = 0; i < len; i++) {
for (let j = 0; j < len1; j++) {
if (data['markets'][i]['baseMarket'] == data['assets'][j]['type'] && data['markets'][i]['quoteMarket'] == "inr") {
const name = data['assets'][j]['name'];
const symbol = data['assets'][j]['type'];
const currency = data['markets'][i]['quoteMarket'];
const price = data['markets'][i]['buy'];
html += "<tr><td>" + name + "</td><td>" + symbol + "</td><td>" + currency + "</td><td>" + price + "</td></tr>";
}
}
}
// we have the new HTML - update the DOM only once per API call
document.getElementById('details').innerHTML = html;
}
(I took the liberty of declaring the variables where they are needed rather than globally)
现在:这是一个使用 flatMap、filter、map 等数组方法清理 for 循环的替代方法
const api_url = "https://api.wazirx.com/api/v2/market-status";
async function get_data_from_api() {
try {
const response = await fetch(api_url);
const data = await response.json();
document.getElementById('details').innerHTML = Object.values(data.markets)
.flatMap((market) =>
Object.values(data.assets)
// your if condition
.filter((asset) => market.baseMarket == asset.type && market.quoteMarket == 'inr')
.map((asset) => {
const { name, type: symbol } = asset;
const { quoteMarket: currency, buy: price } = market;
return `<tr><td>${name}</td><td>${symbol}</td><td>${currency}</td><td>${price}</td></tr>`;
})
).join('');
} catch(error) {
// handle error
}
setTimeout(get_data_from_api, 1000);
}
get_data_from_api();
不确定,但这段代码可能只更新价格
const api_url = "https://api.wazirx.com/api/v2/market-status";
async function get_data_from_api() {
try {
const target = document.getElementById('details');
const response = await fetch(api_url);
const data = await response.json();
const addedHtml = Object.values(data.markets)
.flatMap((market) =>
Object.values(data.assets)
// your if condition
.filter((asset) => market.baseMarket == asset.type && market.quoteMarket == 'inr')
.map((asset) => {
const { name, type: symbol } = asset;
const { quoteMarket: currency, buy: price } = market;
return { id, name, symbol, currency, price };
})
)
.map(({ name, symbol, currency, price }) => {
const id = `${name}${symbol}${currency}`;
let el = target.querySelector(`#${id}`);
if (el) {
el.textContent = price;
return '';
} else {
return `<tr><td>${name}</td><td>${symbol}</td><td>${currency}</td><td id="${id}">${price}</td></tr>`;
}
});
if (addedHTML.length) {
target.insertAdjacentHTML('beforeend', addedHtml.join(''));
}
} catch(error) {
// handle error
}
setTimeout(get_data_from_api, 1000);
}
get_data_from_api();
除了已接受的答案。我还建议您在下面使用带有 wait
函数的 while 循环,而不是 setInterval
.
setInterval 可能会不必要地调用 API。例如。第一次调用 api,api 需要一秒响应,同时你调用 api 第二次它响应只有 100 毫秒,实际上,你不会看到第一次的结果,因为第二次调用会立即更新第一次调用。
const api_url = "https://api.wazirx.com/api/v2/market-status";
const wait = ms => new Promise(res => setTimeout(res, ms));
(async function run() {
while (true) {
try {
const response = await fetch(api_url);
const data = await response.json();
//html jobs.....
await wait(1000);
} catch (err) {
console.log(err);
continue;
}
}
})();
我有一个 table 行内容是从 API 中获取的,而我使用 setinterval 函数只是重复更新的 table 行内容。
例如:(这是一个示例输出,不是实际的)
假设我有内容
John price 2000
在 1 秒的时间间隔后,它应该从 API 更新新值,例如
John price 2200
但我得到的是每次它刷新它只是添加像
John price 2000
John price 2200
John price 2120 ......
我的代码:
<table class="table">
<thead class="thead-dark">
<tr>
<th>Coin</th>
<th>Symbol</th>
<th>Currency</th>
<th>Price</th>
</tr>
</thead>
<tbody id="details">
<tbody>
</table>
var data, len, len1, name, symbol, currency, price;
const api_url = "https://api.wazirx.com/api/v2/market-status";
async function get_data_from_api() {
const response = await fetch(api_url);
data = await response.json();
len = Object.keys(data["markets"]).length;
len1 = Object.keys(data["assets"]).length;
for (let i = 0; i < len; i++) {
for (let j = 0; j < len1; j++) {
if (data['markets'][i]['baseMarket'] == data['assets'][j]['type'] && data['markets'][i]['quoteMarket'] == "inr") {
name = data['assets'][j]['name'];
symbol = data['assets'][j]['type'];
currency = data['markets'][i]['quoteMarket'];
price = data['markets'][i]['buy'];
document.getElementById('details').innerHTML += "<tr><td>" + name + "</td><td>" + symbol + "</td><td>" + currency + "</td><td>" + price + "</td></tr>";
}
}
}
}
get_data_from_api();
setInterval(get_data_from_api, 1000);
您只是将内容附加到节点
document.getElementById('details').innerHTML += "<tr><td>"+name+"</td><td>"+symbol+"</td><td>"+currency+"</td><td>"+price+"</td></tr>";
如果您有多个满足条件的节点,则必须在循环外将内容设置为空。
document.getElementById('details').innerHTML = "";
如果只有一个节点满足条件就直接赋值
document.getElementById('details').innerHTML = "<tr><td>"+name+"</td><td>"+symbol+"</td><td>"+currency+"</td><td>"+price+"</td></tr>";
工作解决方案将是这样的。
var data, len, len1, name, symbol, currency, price;
const api_url = "https://api.wazirx.com/api/v2/market-status";
async function get_data_from_api() {
const response = await fetch(api_url);
document.getElementById('details').innerHTML = '';
data = await response.json();
len = Object.keys(data["markets"]).length;
len1 = Object.keys(data["assets"]).length;
for (let i = 0; i < len; i++) {
for (let j = 0; j < len1; j++) {
if (data['markets'][i]['baseMarket'] == data['assets'][j]['type'] && data['markets'][i]['quoteMarket'] == "inr") {
name = data['assets'][j]['name'];
symbol = data['assets'][j]['type'];
currency = data['markets'][i]['quoteMarket'];
price = data['markets'][i]['buy'];
document.getElementById('details').innerHTML += "<tr><td>" + name + "</td><td>" + symbol + "</td><td>" + currency + "</td><td>" + price + "</td></tr>";
}
}
}
}
get_data_from_api();
setInterval(get_data_from_api, 1000);
您的代码不断添加到 table 的原因是因为您只添加了
document.getElementById('details').innerHTML += " ..... "
所以,当然这只会增加
天真的解决方案是在清除 innerHTML 的循环之前添加代码
document.getElementById('details').innerHTML = ""
一个更好的解决方案是在循环之前初始化一个字符串变量,添加到循环内的字符串,然后在循环之后一次更新innerHTML
const api_url = "https://api.wazirx.com/api/v2/market-status";
async function get_data_from_api() {
const response = await fetch(api_url);
const data = await response.json();
const len = Object.keys(data["markets"]).length;
const len1 = Object.keys(data["assets"]).length;
// this will hold the new HTML
let html = "";
for (let i = 0; i < len; i++) {
for (let j = 0; j < len1; j++) {
if (data['markets'][i]['baseMarket'] == data['assets'][j]['type'] && data['markets'][i]['quoteMarket'] == "inr") {
const name = data['assets'][j]['name'];
const symbol = data['assets'][j]['type'];
const currency = data['markets'][i]['quoteMarket'];
const price = data['markets'][i]['buy'];
html += "<tr><td>" + name + "</td><td>" + symbol + "</td><td>" + currency + "</td><td>" + price + "</td></tr>";
}
}
}
// we have the new HTML - update the DOM only once per API call
document.getElementById('details').innerHTML = html;
}
(I took the liberty of declaring the variables where they are needed rather than globally)
现在:这是一个使用 flatMap、filter、map 等数组方法清理 for 循环的替代方法
const api_url = "https://api.wazirx.com/api/v2/market-status";
async function get_data_from_api() {
try {
const response = await fetch(api_url);
const data = await response.json();
document.getElementById('details').innerHTML = Object.values(data.markets)
.flatMap((market) =>
Object.values(data.assets)
// your if condition
.filter((asset) => market.baseMarket == asset.type && market.quoteMarket == 'inr')
.map((asset) => {
const { name, type: symbol } = asset;
const { quoteMarket: currency, buy: price } = market;
return `<tr><td>${name}</td><td>${symbol}</td><td>${currency}</td><td>${price}</td></tr>`;
})
).join('');
} catch(error) {
// handle error
}
setTimeout(get_data_from_api, 1000);
}
get_data_from_api();
不确定,但这段代码可能只更新价格
const api_url = "https://api.wazirx.com/api/v2/market-status";
async function get_data_from_api() {
try {
const target = document.getElementById('details');
const response = await fetch(api_url);
const data = await response.json();
const addedHtml = Object.values(data.markets)
.flatMap((market) =>
Object.values(data.assets)
// your if condition
.filter((asset) => market.baseMarket == asset.type && market.quoteMarket == 'inr')
.map((asset) => {
const { name, type: symbol } = asset;
const { quoteMarket: currency, buy: price } = market;
return { id, name, symbol, currency, price };
})
)
.map(({ name, symbol, currency, price }) => {
const id = `${name}${symbol}${currency}`;
let el = target.querySelector(`#${id}`);
if (el) {
el.textContent = price;
return '';
} else {
return `<tr><td>${name}</td><td>${symbol}</td><td>${currency}</td><td id="${id}">${price}</td></tr>`;
}
});
if (addedHTML.length) {
target.insertAdjacentHTML('beforeend', addedHtml.join(''));
}
} catch(error) {
// handle error
}
setTimeout(get_data_from_api, 1000);
}
get_data_from_api();
除了已接受的答案。我还建议您在下面使用带有 wait
函数的 while 循环,而不是 setInterval
.
setInterval 可能会不必要地调用 API。例如。第一次调用 api,api 需要一秒响应,同时你调用 api 第二次它响应只有 100 毫秒,实际上,你不会看到第一次的结果,因为第二次调用会立即更新第一次调用。
const api_url = "https://api.wazirx.com/api/v2/market-status";
const wait = ms => new Promise(res => setTimeout(res, ms));
(async function run() {
while (true) {
try {
const response = await fetch(api_url);
const data = await response.json();
//html jobs.....
await wait(1000);
} catch (err) {
console.log(err);
continue;
}
}
})();