节点js中的同步http请求?

时间:2016-02-15 13:52:01

标签: node.js synchronous

我正在寻找一种在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;
}

2 个答案:

答案 0 :(得分:0)

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

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

 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
    }

答案 1 :(得分:0)

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

“Promise是表示异步操作最终完成或失败的对象” reference

即:

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;

}