Node.js 如何使用Rxjs按顺序解析http请求

Node.js 如何使用Rxjs按顺序解析http请求,node.js,reactive-programming,rxjs5,Node.js,Reactive Programming,Rxjs5,我有一个像这样的js对象 var routes = [ {lat: 12.44, lng: 74.50}, {lat: 12.54, lng: 74.60}, {lat: 12.64, lng: 74.70}, ... ]; 我想计算routes阵列中两个点之间的距离,以创建一个包含lat、lng和距离上一个点的新阵列。使用递归函数,我可以按顺序执行,所以在http请求未解决之前,我不会调用下一个点。下面是递归代码 var finalData = []; fun

我有一个像这样的js对象

var routes = [
    {lat: 12.44, lng: 74.50},
    {lat: 12.54, lng: 74.60},
    {lat: 12.64, lng: 74.70},
    ...
];
我想计算routes阵列中两个点之间的距离,以创建一个包含lat、lng和距离上一个点的新阵列。使用递归函数,我可以按顺序执行,所以在http请求未解决之前,我不会调用下一个点。下面是递归代码

var finalData = [];
function getData(points, i) {
    if(points.length >= i+1) {
        var p1 = points[i];
        var p2 = points[i+1];
        var url = 'http://to/web/app/origin=' + p1.lat + ',' + p1.lng + '&destination=' + p2.lat + ',' + p2.lng;
        http.get(url, function(res) {
            var data = '';
            res.on('data', function(chunk) {
                data += chunk;
            });
            res.on('end', function() {
                var d = JSON.parse(data);
                finalData.push({
                    lat: p2.lat,
                    lng: p2.lng,
                    distance: d.dis
                });
                getData(points, i+1);
            });
        });
    }
}
getData(routes, 0);

作为反应式编程的新手,我无法思考和发现如何使用Rxjs库实现同样的功能?我指的是一些小的声明性代码。

您似乎并不需要递归地执行此操作,因为您有一个将要使用的项目列表:

//Make your callback function `Observable`
const observableHttp = Rx.Observable.bindCallback(http.get);
//Optionally if it is a node-style callback
//const observableHttp = Rx.Observable.bindNodeCallback(http.get);

Rx.Observable.from(routes)
  //Combine each of the elements into pairwise arrays
  .pairwise()
  //Maintain the order of the responses
  .concatMap(points => {
    const p1 = points[0];
    const p2 = points[1];
    return observableHttp(`http://to/web/app/origin=${p1.lat},${p1.lng}` + 
                          `&destination=${p2.lat},${p2.lng}`);
  },
  //Process the response along with the original array of responses 
  (points, res) => ({lat: points[1].lat, lng: points[1].lng, distance: res.dis}))
  //Gather all the values into a single array
  .toArray()
  .subscribe(x => /*Do something with your array of values*/

似乎您实际上不需要递归地执行此操作,因为您有一个要使用的项目列表:

//Make your callback function `Observable`
const observableHttp = Rx.Observable.bindCallback(http.get);
//Optionally if it is a node-style callback
//const observableHttp = Rx.Observable.bindNodeCallback(http.get);

Rx.Observable.from(routes)
  //Combine each of the elements into pairwise arrays
  .pairwise()
  //Maintain the order of the responses
  .concatMap(points => {
    const p1 = points[0];
    const p2 = points[1];
    return observableHttp(`http://to/web/app/origin=${p1.lat},${p1.lng}` + 
                          `&destination=${p2.lat},${p2.lng}`);
  },
  //Process the response along with the original array of responses 
  (points, res) => ({lat: points[1].lat, lng: points[1].lng, distance: res.dis}))
  //Gather all the values into a single array
  .toArray()
  .subscribe(x => /*Do something with your array of values*/

通过@paulpdaniels扩展答案,我能够修复我的代码。如果有人感兴趣,就把它放在这里

Rx.Observable.from(data)
    .pairwise()
    .concatMap(points => {
        const p1 = points[0];
        const p2 = points[1];
        var url = `http://to/web/app?origins=${p1.lat},${p1.lng}` + 
                         `&destinations=${p2.lat},${p2.lng}`;
        return GetDataStream(url);
    },
    //Process the response along with the original array of responses 
    (points, dis) => {          
        return {lat: points[1].lat, lng: points[1].lng, distance: dis};
    })
    .toArray()
    .subscribe(x => console.log(x));
她是可以观察到的习惯

const GetDataStream = function(url) {
    return Rx.Observable.create(observer => {
        http.get(url, res => {
            var _data = ''
            res.on('data', chunk => {
                _data += chunk;
            });
            res.on('end', () => {
                var d = JSON.parse(_data);
                var distance = d.rows[0].elements[0].distance.value;
                observer.next(distance);
                observer.complete();
            });
        });
    });
}

通过@paulpdaniels扩展答案,我能够修复我的代码。如果有人感兴趣,就把它放在这里

Rx.Observable.from(data)
    .pairwise()
    .concatMap(points => {
        const p1 = points[0];
        const p2 = points[1];
        var url = `http://to/web/app?origins=${p1.lat},${p1.lng}` + 
                         `&destinations=${p2.lat},${p2.lng}`;
        return GetDataStream(url);
    },
    //Process the response along with the original array of responses 
    (points, dis) => {          
        return {lat: points[1].lat, lng: points[1].lng, distance: dis};
    })
    .toArray()
    .subscribe(x => console.log(x));
她是可以观察到的习惯

const GetDataStream = function(url) {
    return Rx.Observable.create(observer => {
        http.get(url, res => {
            var _data = ''
            res.on('data', chunk => {
                _data += chunk;
            });
            res.on('end', () => {
                var d = JSON.parse(_data);
                var distance = d.rows[0].elements[0].distance.value;
                observer.next(distance);
                observer.complete();
            });
        });
    });
}

实际上res不是数据对象,而是它的事件对象。所以实际数据是在res.end事件中检索到的,我已经更新了问题,请查看。实际上res不是数据对象,而是它的事件对象。所以实际数据是在res.end事件中检索到的,我已经更新了问题,请查看。