节点js中的同步http请求?

Synchronous http request in node js?

我正在寻找一种在 node.js 中执行同步 http 请求的简单方法,但它仍然收到异步响应...

我意识到 node.js 被推荐用于异步作业,但就我而言, 我需要同步响应来调用使用此数据的其他函数,如果它是 null/undefined,我无法继续流程... 这样做的更好方法是什么?

这是我的代码:

function callCellId(data) {
  console.log("Data: " + data);
  var towers = [],
      rscp = [];
  var request = require('sync-request');
  for (var x = 0; x < data.length; x++) {
    console.log("Request data: \n");
    rscp[x] = data[x].rscp;
    var res = request('POST', 'http://opencellid.org/cell/get?key=xxxxx&mcc=' + data[x].mcc + '&mnc=' + data[x].mnc + '&lac=' + data[x].LAC + '&cellid=' + data[x].cellID + '&format=json');
    console.log("loop " + x);
    data = res.getBody().toString();
    console.log("rsp: " + data);
    towers[x] = {
      'latitude': data.lat,
      'longitude': data.lon,
      'rscp': rscp[x],
      'signal': data.averageSignalStrength
    };
  }
  console.log("Content for triangulation" + JSON.stringify(towers));
  return towers;
}

在循环云中使用异步很棘手。

我在没有外部库的情况下使用生成器解决了这个问题:

 LoopOperation: function() {

        //define generator with the main loop
        var loopIterator = function*() {
            for (var index = 0; index < 10; index++) {
              var result = yield asyncOperation( (res) => loopIterator.next(res)); //do something asyc and execute () => loopIterator.next() when done as callback
              console.log(result);
            }
        }();

        loopIterator.next(); //start loop
    }

由于 nodejs 的本质是异步的,每次我们需要一些同步调用(比如这个嵌套的请求堆栈)时,我们都可以使用 promises

"A Promise is an object representing the eventual completion or failure of an asynchronous operation" reference

I.E:

const request = require('request-promise');

function callCellId(data) {
 
  let towers = [];
  let options = {
    url: 'http://opencellid.org/cell/get',
    method: 'POST',
    json: true
  };

  data.forEach(location => {

    options.body = {
      key: 'YOUR_PRIVATE_KEY',
      mcc: location.mcc,
      mnc: location.mnc,
      lac: location.lac,
      cellId: location.cellID
    }

    request(options).then(cellInfo => {

      towers.push({
        latitude: cellInfo.lat,
        longitude: cellInfo.lon,
        rscp: location.rscp,
        signal: cellInfo.averageSignalStrength
      });

    }).catch(err => {
      console.log('Could not get cellId Info for',location);
      console.log(err);
    });

  });

  return towers;

}