javascript - data.map 函数在第二次调用后停止工作
问题描述
我有一个脚本,它每小时调用 API 并接收数据并自动将其存储在数据库中。该脚本本身在第一次调用时没有任何问题,但是当有时间第二次调用脚本时,它会给我一个错误。
示例:我在 13:30 开始脚本,在 14:00 脚本开始接收数据并将其存储在 MongoDB 中。第一次运行良好,但是当另一个时间到来时(在 15:00),脚本不想启动并且我收到此错误 -TypeError: data.map is not a function
我猜测问题出setTimeout
在我添加之前的功能原因,一切都很完美。问题是我需要有 2 秒的延迟,否则我会收到来自 API 的 IP 禁令。
完整代码示例:
var requestPromise = require('request-promise');
const { MongoClient } = require('mongodb');
const schedule = require('node-schedule');
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
const fetch = require("node-fetch");
var symbols = ["ZRXBTC",
"LENDBTC",
"AEBTC",
"AIONBTC",
"ALGOBTC",
"ARDRBTC",
];
let cnt = 0;
const callIt = () => {
fetch(`https://api.binance.com/api/v3/klines?symbol=${symbols[cnt]}&interval=30m&limit=1`)
.then(res => res.json())
.then(data => {
const btcusdtdata = data.map(d => {
return {
Open: parseFloat(d[1]),
High: parseFloat(d[2]),
Low: parseFloat(d[3]),
Close: parseFloat(d[4]),
Volume: parseFloat(d[5]),
Timespan: 30,
}
});
console.log(btcusdtdata);
saveToDatebase(btcusdtdata);
cnt++;
if (cnt < symbols.length) setTimeout(callIt, 3000);
})
.catch((err) => {
console.log(err);
})
};
const j = schedule.scheduleJob('*/0 * * * *', callIt)
const saveToDatebase = function(BTCdata) {
const url = 'mongodb+srv://username:password3@cluster0-1kunr.mongodb.net/<dbname>?retryWrites=true&w=majority';
var today = new Date();
var date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
var dateTime = date + ' ' + time;
MongoClient.connect(url, { useNewUrlParser: true, useUnifiedTopology: true }, (err, db) => {
if (err) throw err;
const dbo = db.db('CryptoCurrencies');
const myobj = { Name: symbols[cnt - 1], Array: BTCdata, Date: dateTime };
dbo.collection(`${symbols[cnt - 1]}`).insertOne(myobj, (error, res) => {
if (error) throw error;
console.log('1 document inserted');
db.close();
});
});
};
很快:该脚本每小时接收一次数据并将其存储在 MongoDB 中。我需要使用 setTimeout 从数组中延迟调用属性,否则我将收到来自 API 的 IP 禁令。该脚本在第一次工作时很好,但是当需要第二次调用时它给我一个错误 - TypeError: data.map is not a function
。
只有在我添加setTimeout()
功能后才会出现此问题。
解决方案
I think the problem is that the cnt
variable is not reset to 0
, returning undefined
in the url on the second run (symbols[symbols.length] === undefined
), returning a 404
from the fetch call, having no json body and thus dereferencing map
on a non-array object.
Edit: The simple solution is to reset the counter to 0 once it has reached the end of the array.
const callIt = () => {
fetch(`https://api.binance.com/api/v3/klines?symbol=${symbols[cnt]}&interval=30m&limit=1`)
.then(res => res.json())
.then(data => {
const btcusdtdata = data.map(d => {
return {
Open: parseFloat(d[1]),
High: parseFloat(d[2]),
Low: parseFloat(d[3]),
Close: parseFloat(d[4]),
Volume: parseFloat(d[5]),
Timespan: 30,
}
});
console.log(btcusdtdata);
saveToDatebase(btcusdtdata);
cnt++;
if (cnt < symbols.length) {
setTimeout(callIt, 3000);
} else {
cnt = 0; // reset counter to 0 when cnt >= symbols.length to "prepare" for the next iteration initiated by schedule.scheduleJob
}
})
.catch((err) => {
console.log(err);
})
};
推荐阅读
- python - Python commpy 库错误:没有名为“过滤器”的模块
- f# - 如何为函数组合选择正确的方法重载?
- javascript - 无法获得承诺函数的原始返回值
- python-3.x - 如何将小部件添加到现有屏幕?
- c++ - 我必须在 SFML 应用程序中使用 GLAD 加载程序吗?
- javascript - 查找和替换字符串 - 忽略大小写和非字母字符
- c# - 如何在我的 c# 程序中使这个 bool 工作
- java - 如何编译模块具有不同 Java 版本的多模块 Maven 项目?可能使用Jenv?
- javascript - 道具类型失败:提供给“表”的“函数”类型的无效道具“rowSelection”,应为“对象”
- kubernetes - 带有 Kubernetes 的 Spring Cloud Gateway 用于限制传入流量