在JavaScript中同步调用RESTAPI

在JavaScript中同步调用RESTAPI,javascript,node.js,rest,npm,synchronization,Javascript,Node.js,Rest,Npm,Synchronization,我不熟悉JavaScript和npm世界。我尝试通过REST post调用将一些数据上传到我的REST服务。我从csv文件中获取这些数据。到现在为止,一直都还不错。在每个获取的行上,我转换数据(满足我的需要),并调用restapi来上传这些数据。因为我有很多行(大约700行),所以API经常被连续调用。打了几个电话(大概500个左右)后,我收到了一个套接字错误 events.js:136 throw er; // Unhandled 'error' event ^ Er

我不熟悉JavaScript和npm世界。我尝试通过REST post调用将一些数据上传到我的REST服务。我从csv文件中获取这些数据。到现在为止,一直都还不错。在每个获取的行上,我转换数据(满足我的需要),并调用restapi来上传这些数据。因为我有很多行(大约700行),所以API经常被连续调用。打了几个电话(大概500个左右)后,我收到了一个套接字错误

events.js:136
      throw er; // Unhandled 'error' event
      ^

Error: connect ECONNRESET 127.0.0.1:3000
    at Object._errnoException (util.js:999:13)
    at _exceptionWithHostPort (util.js:1020:20)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1207:14)
我想这是因为我经常调用restapi。我不明白的是: 我应该如何同步拨打电话以避免如此多的连接? 或者我不应该? 在JS中,什么是合适的解决方案

我已经尝试过承诺等等,但所有这些都没有帮助,而是先解决了一些函数调用的问题

这是我的代码:

readCsv()

function readCsv() {
    var csvFile = csvFiles.pop()
    if (csvFile) {
        csv({ delimiter: ";" }).fromFile(csvFile).on('json', async (csvRow) => {
            if (/.*\(NX\)|.*\(NI\)|.*\(NA\)|.*\(WE\)|.*\(RA\)|.*\(MX\)/.test(csvRow["Produkt"])) {
                var data = await addCallLog(
                    csvRow["Datum"],
                    csvRow["Zeit"],
                    csvRow["Menge-Zeit"],
                    csvRow["Zielrufnummer"],
                    csvRow["Produkt"]);
            }
        }).on('done', (error) => {
            //console.log('end')
            readCsv()
        })
    } else {

    }
}

function addCallLog(date, time, duration, number, product) {
    return new Promise(resolve => {
        args.data = { number: number, name: "", timestamp: getTimestamp(date, time), duration: getDuration(duration), type: "OUTGOING" }
        client.methods.addCallLog(args, (data, response) => {
            // client.methods.getCallLog((data, response) => {
            //     console.log(data)
            // })
            //console.log("addCallLog resolve")
            resolve(data)
        })
    })
}

正如您所看到的,我在并行读取多个csv文件时遇到了相同的问题。我通过递归调用readCsv函数解决了这个问题,并在文件读取完成后弹出下一个文件

不能同步调用事物。但是,您可以对异步REST调用进行排序,我想这就是您的意思


这里的一个问题是,
await addCallLog()
不会阻止下一个
json
事件的生成,因此您将在同一时间以大量请求结束,而且显然您的请求太多,资源不足

一种方法是将需要的行收集到一个数组中,然后使用常规的
for
循环来迭代该数组,您可以在
for
循环中成功地使用
wait
。下面是它的样子:

readCsv()

function readCsv() {
    var csvFile = csvFiles.pop()
    if (csvFile) {
        let rows = [];
        csv({ delimiter: ";" }).fromFile(csvFile).on('json', (csvRow) => {
            if (/.*\(NX\)|.*\(NI\)|.*\(NA\)|.*\(WE\)|.*\(RA\)|.*\(MX\)/.test(csvRow["Produkt"])) {
                rows.push(csvRow);
            }
        }).on('done', async (error) => {
            for (let csvRow of rows) {
                var data = await addCallLog(
                    csvRow["Datum"],
                    csvRow["Zeit"],
                    csvRow["Menge-Zeit"],
                    csvRow["Zielrufnummer"],
                    csvRow["Produkt"]
                );
            }
            readCsv();
        })
    } else {

    }
}

function addCallLog(date, time, duration, number, product) {
    return new Promise(resolve => {
        args.data = { number: number, name: "", timestamp: getTimestamp(date, time), duration: getDuration(duration), type: "OUTGOING" }
        client.methods.addCallLog(args, (data, response) => {
            // client.methods.getCallLog((data, response) => {
            //     console.log(data)
            // })
            //console.log("addCallLog resolve")
            resolve(data)
        })
    })
}
您的编码似乎缺少错误处理。
client.methods.addCallLog()
需要一种返回错误的方法


您可能还需要csv迭代器的
错误
事件处理程序。

在prev中填充缓冲区后。函数I检查缓冲区中的数据,并使用promise的“then”回调逐个上传这些数据

var callLogBuffer = []

checkForUpload()

function checkForUpload() {
    console.log("checkForUpload")
    if (callLogBuffer.length > 0) {
        addCallLog(callLogBuffer.pop()).then((data) => {
            checkForUpload()
        })
    }
}


function addCallLog(callLog) {
    return new Promise(resolve => {
        args.data = { number: callLog.number, name: "", timestamp: getTimestamp(callLog.date, callLog.time), duration: getDuration(callLog.duration), type: "OUTGOING" }
        client.methods.addCallLog(args, (data, response) => {
            // client.methods.getCallLog((data, response) => {
            //     console.log(data)
            // })
            //console.log("addCallLog resolve")
            resolve(data)
        })
    })
}

这里可能重复的问题是
await addCallLog()
不会阻止下一个
json
事件的生成,因此您将在同一时间以大量请求结束,而且显然您的请求太多,以至于资源耗尽。这里的一种可能性是将所有json数据收集到一个数组中,然后使用
for
循环来迭代您的请求所在的数组
await addCallLog()
将用于序列化请求。您使用的是什么csv模块?我使用的是CSVTOJSON为什么要进行向下投票?如果你至少不发表评论的话,我的答案是无法改进的。这就解决了我的问题!非常感谢。使用缓冲区意味着我是与我相关的人。我也改变了我的代码,不再使用wait,而是使用promise的“then”回调。现在它的工作就像一个魅力。顺便说一句,实际上我没有投反对票。至少我最终投了赞成票:)@burix-很高兴你的问题得到了解决,但我不知道你所说的“切换到.然后()`因为是
for
循环中的
await
使事情一次运行一个,以防止一次运行太多请求。我使用了承诺的函数回调,而不是async/await。它现在就像一个递归调用。但最重要的部分是引入一个缓冲区,在那里我首先填充了我在下面的答案中发布了我的最终解决方案。。。