Javascript data.map函数在第二次调用后停止工作

Javascript data.map函数在第二次调用后停止工作,javascript,Javascript,我有一个脚本,它调用API,每小时接收一次数据,并自动将其存储在数据库中。 脚本本身在第一次调用时不会出现任何问题,但当第二次调用脚本时,它会给我一个错误 示例:我在13:30启动脚本,在14:00脚本开始接收数据并将其存储在MongoDB中。第一次运行良好,但当另一次在15:00出现时,脚本不想启动,我收到此错误-TypeError:data.map不是函数 我猜问题在于setTimeout函数,因为在我添加它之前,一切都运行得很好。问题是,我需要有2秒的延迟,否则我将收到来自API的IP禁令

我有一个脚本,它调用API,每小时接收一次数据,并自动将其存储在数据库中。 脚本本身在第一次调用时不会出现任何问题,但当第二次调用脚本时,它会给我一个错误

示例:我在13:30启动脚本,在14:00脚本开始接收数据并将其存储在MongoDB中。第一次运行良好,但当另一次在15:00出现时,脚本不想启动,我收到此错误-TypeError:data.map不是函数

我猜问题在于setTimeout函数,因为在我添加它之前,一切都运行得很好。问题是,我需要有2秒的延迟,否则我将收到来自API的IP禁令

完整代码示例:

简而言之:该脚本每小时接收一次数据并将其存储在MongoDB中。我需要使用setTimeout延迟从数组调用属性,否则我将从API接收IP禁止。该脚本在第一次运行时很好,但在第二次调用时,它会给我一个错误-TypeError:data.map不是一个函数


这个问题只有在我添加setTimeout函数后才会出现。

我认为问题在于cnt变量没有重置为0,在第二次运行时返回url中未定义的符号[symbols.length]==未定义,从fetch调用返回404,没有json主体,因此在非数组对象上取消引用映射

编辑: 简单的解决方案是在计数器到达数组末尾后将其重置为0

常量callIt==>{ 取回`https://api.binance.com/api/v3/klines?symbol=${symbols[cnt]}&间隔=30m&限制=1` .thenres=>res.json .thendata=>{ 常量btcusdtdata=data.mapd=>{ 返回{ 打开:已解析浮动[1], 高:解析为浮动[2], 低:已解析浮点[3], 关闭:已解析为浮动[4], 卷:已解析为浮动[5], 时间跨度:30, } }; console.logbtcusdtdata; SaveToDateBaseBcusdtData; cnt++; 如果cnt=symbols.length时,将计数器重置为0,以准备schedule.scheduleJob启动的下一次迭代 } } .catcherr=>{ console.logerr; } };
正如Shikkie已经指出的,问题在于cnt永远不会重置为零

然而,它目前的整个工作方式有点迂回,无论如何,可以通过使用异步函数来清理它,从而也消除了问题:

//这给了我们一个异步函数延迟,等待给定的时间量 const delay=ms=>new Promiseresolve=>setTimeoutresolve,ms //这是callIt的新定义-不再在外部声明cnt变量 常量callIt=async=>{ 符号的常量符号{ 试一试{ const res=等待取数`https://api.binance.com/api/v3/klines?symbol=${symbol}&间隔=30m&限制=1` const data=wait res.json const ticker=data.mapd=>{ 打开:已解析浮动[1], 高:解析为浮动[2], 低:已解析浮点[3], 关闭:已解析为浮动[4], 卷:已解析为浮动[5], 时间跨度:30 } console.log`接收到${symbol}:`的ticker,ticker //这听起来像是异步的,所以也许你想 //检查此函数内部如何处理错误以避免 //由于异步错误导致整个进程崩溃。您可以返回 //函数的一个承诺,然后在这里等待它。 //此外,我不明白你在这里如何区分个人 //市场对…也许你也想传递变量'symbol'。 saveToDatebaseticker //等待3秒钟,然后再执行下一个请求 等待延迟3000 }犯错误{ console.error`处理${symbol}时出错:`,错误 } } }
注意:延迟函数也可以使用require'util.promisifysetTimeout生成,但是我现在编写的方法更独立于平台,不依赖node.js作为环境。

顺便说一句,您需要三个库来处理HTTP请求,这似乎有点没用。一个就够了。
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();
        });
    });

};