【发布时间】:2020-06-19 11:13:22
【问题描述】:
这是来自该线程的一个继续问题 - setTimeout inside a loop, stops script from working
我有一个脚本,它从 API 接收数据并将其存储在 MongoDB 集合中。
问题是setTimeout() 不允许脚本第二次运行。
我 99.9% 确定问题出在这上面。
问题概述 - Watch Out When Using SetTimeout() in For Loop #JS
有问题的代码区:
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);
})
};
此脚本正在调用 API,然后通过数组接收符号。 setTimeout() 遍历整个数组后如何停止?
我试图添加类似clearTimeout(callIt) 的内容对我不起作用。
EDIT1
错误:-TypeError: data.map is not a function
全码
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('*/1 * * * *', callIt)
const saveToDatebase = function(BTCdata) {
const url = 'mongodb+srv://username:password@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();
});
});
};
【问题讨论】:
-
if (cnt < symbols.length)不会负责停止脚本吗?为什么你需要一个额外的clearTimeout? -
@Tibebes.M 基本上。该脚本第一次运行,但是当它应该第二次启动时给了我一个错误。我将使用完整的代码示例编辑主要问题。
-
timer = setTimeout(); ... clearTimeout(timer)- 您传递的是回调而不是超时索引 -
“当它应该开始时给我一个错误” - 总是,总是包括错误细节。
-
@Justinas 你能否提供示例原因当我尝试你的代码时(也许我做错了)它会立即启动脚本,但它假设每小时开始使用 node-schedule 包工作
标签: javascript typescript ecmascript-6 settimeout