Node.js中的同步api调用

时间:2018-09-17 13:33:15

标签: node.js request node-cron

我有一个cronjob,每10秒运行一次。它为单个客户端请求计算机,并根据响应进行计算,然后必须在for循环中使用这些计算来更新或创建文档。但是,直到执行了for循环并且发送到api调用的数据是最后一台机器的错误数据之后,代码中“ ***”之后的api调用才会发生。我想通过这种方式或其他可能的方式解决此问题。我的代码如下:

// index.js
const cron = require("node-cron");
const express = require("express");
const fs = require("fs");
const request = require("request");

app = express();

var clientId = 'ABCD';
var apiUrl = 'http://example.com:3001/';
var getMachines                     = apiUrl + 'getMachines/',
    updateMachine                   = apiUrl + 'updateMachine/',
    getControlRoomStatus            = apiUrl + 'getControlRoomStatus/',
    registerControlRoomStatus       = apiUrl + 'registerControlRoomStatus/',
    updateControlRoomStatus         = apiUrl + 'updateControlRoomStatus/';

cron.schedule("*/10 * * * * *", function() {
    APICall(getMachines, { 'clientId' : clientId }, 'POST', function(err, machines) {
        if (err) {
            console.log(err);
        } else {
            console.log('--------------------------------------------------------------------------------------------------');
            var allMachines = machines;
            var currentDateTime = IST();
            for (var i = 0; i < 2; i++) {
                var lastCycleTime = new Date(allMachines[i]['lastCycleTime']);
                var lastHeartbeat = new Date(allMachines[i]['lastHeartbeat']);
                var machineData;
                var controlRoomData;
                var machineId = {
                    'machineId' : allMachines[i]['machineId']
                };
                console.log(machineId);
                if (allMachines[i]['downtimeStatus'] == '0') {
                    if ((currentDateTime - lastCycleTime)>300000) {
                        if ((currentDateTime - lastHeartbeat)>300000) {
                            console.log(allMachines[i]['machineId'] ,' No Internet');
                            controlRoomData = {
                                'clientId': clientId,
                                'lastTimeStamp': allMachines[i]['lastCycleTime'], 
                                'status': 'Inactive',
                                'type': 'No Internet/Power'
                            };
                        } else {
                            console.log(allMachines[i]['machineId'] ,' No button pressed');
                            controlRoomData = {
                                'clientId': clientId,
                                'lastTimeStamp': allMachines[i]['lastCycleTime'], 
                                'status': 'Inactive',
                                'type': 'No Button Pressed'
                            };
                        }
                        machineData = {
                            'status' : 'Inactive'
                        };
                    } else {
                        console.log(allMachines[i]['machineId'] ,' Active');
                        machineData = {
                            'status' : 'Active'
                        };
                        controlRoomData = {
                            'clientId': clientId,
                            'lastTimeStamp': allMachines[i]['lastCycleTime'], 
                            'status': 'Active',
                            'type': 'N.A'
                        };
                    }
                } else {
                    if ((currentDateTime - lastHeartbeat)>300000) {
                        console.log(allMachines[i]['machineId'] ,' button pressed ',' No Internet');
                        controlRoomData = {
                            'clientId': clientId,
                            'lastTimeStamp': allMachines[i]['lastCycleTime'], 
                            'status': 'Inactive',
                            'type': 'No Internet/Power'
                        };
                    } else {
                        var downtimeLength = allMachines[i]['downtimeData'].length - 1;
                        console.log(allMachines[i]['machineId'] ,' button pressed ',allMachines[i]['downtimeData'][downtimeLength]['downtimeType']);
                        controlRoomData = {
                            'clientId': clientId,
                            'lastTimeStamp': allMachines[i]['lastCycleTime'], 
                            'status': 'Inactive',
                            'type': allMachines[i]['downtimeData'][downtimeLength]['downtimeType']
                        };
                    }
                    machineData = {
                        'status' : 'Inactive'
                    };
                }
                ***
                APICall(getControlRoomStatus, machineId, 'POST', function(err, controlRoom) {
                    if (err) {
                        console.log(err);
                    } else {
                        console.log(machineId,controlRoomData);
                        if (controlRoom == null ) {
                            APICall(registerControlRoomStatus, controlRoomData, 'POST', function(err, body) {
                                if (err) {
                                    console.log(err);
                                } else {
                                    // console.log(body);
                                }
                            });
                        } else {
                            var updateControlRooomUrl = (updateControlRoomStatus+''+controlRoom['_id']+'');
                            // console.log(updateControlRooomUrl);
                            APICall(updateControlRooomUrl, controlRoomData, 'PUT', function(err, body) {
                                if (err) {
                                    console.log(err);
                                } else {
                                    // console.log(body);
                                }
                            });
                        }
                    }
                });
                var updateMachineUrl = (updateMachine+''+allMachines[i]['_id']+'');
                // console.log(updateMachineUrl);
                APICall(updateMachineUrl, machineData, 'PUT', function(err, body) {
                    if (err) {
                        console.log(err);
                    } else {
                        console.log(i,machineId);
                        // console.log(body);
                    }
                });
            }
        }
    });
});

function APICall(url, requestData, method, callback) {
    request({
        url: url,
        form: requestData,
        method: method
    }, function (error, response, body) {
        if (error || response.statusCode !== 200) {
            return callback(error || {statusCode: response.statusCode});
        }
        callback(null, JSON.parse(body));  
    });
}

function IST(){
  var dateUTC = new Date();
  var dateUTC = dateUTC.getTime(); 
  var dateIST = new Date(dateUTC);

  dateIST.setHours(dateIST.getHours() + 5); 
  dateIST.setMinutes(dateIST.getMinutes() + 30);
  return dateIST;
}

app.listen(3128);

谢谢。

2 个答案:

答案 0 :(得分:0)

您可以尝试以下软件包:

sync-request

您可以在NPM上找到它。

这是一个使用方法的示例(来自文档):

var request = require('sync-request');
var res = request('GET', 'http://example.com');
console.log(res.getBody());

如文档所述,请勿在生产代码中使用它,因为这将严重阻塞您的服务器,并且会大大降低速度(如果您正在运行所使用的HTTP服务器, express)。

如果您有异步代码,并且想要在异步之后执行一些代码,则还可以使用:

  • 可观察对象(并非本机需要使用软件包,例如RxJS
  • 承诺(本机ES6 JS)

答案 1 :(得分:0)

我使用了一种不同的方法来做事情,现在它正在按预期的方式工作。我使用了“异步”并将for循环替换为以下内容:

RTSP