繁体   English   中英

在 JavaScript 中同步调用 REST API

[英]Synchronously call a REST API in JavaScript

我是 JavaScript 和 npm 世界的新手。 我尝试通过 REST 后调用将一些数据上传到我的 REST 服务。 我从 csv 文件中获取这些数据。 到现在为止还挺好。 在每个提取的行上,我转换数据(根据我的需要)并调用 REST API 来上传这些数据。 由于我有很多行(大约 700 行),因此 API 经常被连续调用。 经过一些电话(猜测 500 左右)后,我收到一个 Socket 错误

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)

我想这是因为我经常调用 REST API。 我不明白的是:我应该如何同步进行调用以避免这么多连接? 还是我不应该? 为此,JS 中的正确解决方案是什么?

我已经尝试过 Promises 等等,但所有这些都没有帮助,但之前将问题移到了一些函数调用......

这是我的代码:

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循环中成功使用await 这就是它的样子:

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 迭代器的error事件处理程序。

在上一页填充缓冲区后。 函数我检查该缓冲区的数据并使用承诺的“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)
        })
    })
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM