我遇到了nodeJS流媒体的问题。我遇到的问题是我的一个流我发送请求,使用请求模块(这是异步的),当请求得到响应时,整个流完成。
这是代码
var fs = require('fs');
var csv = require('fast-csv');
var path = require('path');
var request = require('request');
var JSONStream = require('JSONStream');
var locations = [];
var urls = [];
var MAP_QUEST_KEY = 'mykey';
var MAP_QUEST_URL = 'http://www.mapquestapi.com/geocoding/v1/address?key=' + MAP_QUEST_KEY + '&inFormat=json&json=';
var CSV_FILE_NAME = 'smaller_stores.csv';
var inFile = path.join(__dirname, 'input', CSV_FILE_NAME);
var outFile = path.join(__dirname, 'output', CSV_FILE_NAME);
// create a location object
var createLocationJSONStream = function (data) {
var location = {
street: data.street_no + ' ' + data.street_name,
city: data.city_name,
state: data.state_id
};
var url = MAP_QUEST_URL + JSON.stringify(location);
// this request finishes after stream
request({
url: 'url',
method: 'GET',
json: location
}, function (error, response, body) {
if (error) {
console.log(error);
} else {
data.lat = body.results[0].locations[0].latLng.lat;
data.lng = body.results[0].locations[0].latLng.lng;
}
return data;
});
};
var readFileStream = fs.createReadStream(inFile);
var writeFileStream = fs.createWriteStream(outFile);
var parseCsvStream = csv.parse({
trim: true,
headers: true,
objectMode: false
});
var deserializeJSONStream = JSONStream.parse();
var streamingEvent = readFileStream.pipe(parseCsvStream).transform(createLocationJSONStream).pipe(deserializeJSONStream);
// eventually want to write out to csv
//.pipe(csv.createWriteStream({headers: true}))
//.pipe(fs.createWriteStream(outFile, {encoding: 'utf8'}));
streamingEvent.on('data', function (data) {
console.log(JSON.stringify(data));
});
streamingEvent.on('end', function () {
console.log('end');
});
这是输出:
end
200
application/json; charset=utf-8
200
application/json; charset=utf-8
200
application/json; charset=utf-8
以下是csv示例:
region_id region_name street_no street_name sitetype_id country_name timezone_no geocode_id city_name state_id zip_code county_name
3 West 350 ORCHARD AVE N USA 4 954824536 UKIAH CA 95482-4536 MENDOCINO
1 South 1000 4TH AVE N USA 7 333041903 FORT LAUDERDALE FL 33304-1903 BROWARD
0 Northeast 1370 HURFVILLE RD N USA 7 80963818 DEPTFORD NJ 08096-3818 GLOUCESTER
我知道我正在处理错误的流,但不知道修复它的最简单方法是什么?管道到请求?
答案 0 :(得分:1)
如果您希望在启动流代码之前完成异步request()
操作,则需要将流代码INSIDE放入请求的完成回调中。这样,在您收到request()
操作中的数据之前,您才能启动流代码。
此外,您无法像尝试执行return data;
一样从异步操作返回值。从回调中返回数据只会返回到回调基础架构。外部函数早已返回,并且外部函数之后的后续代码行已经执行。相反,您必须在回调本身内部使用结果,或者从该回调中进行函数调用,并将数据传递给其他函数。
我并不完全遵循您尝试对流进行操作的内容,但如果您想确保request()
操作之前完成var fs = require('fs');
var csv = require('fast-csv');
var path = require('path');
var request = require('request');
var JSONStream = require('JSONStream');
var locations = [];
var urls = [];
var MAP_QUEST_KEY = 'mykey';
var MAP_QUEST_URL = 'http://www.mapquestapi.com/geocoding/v1/address?key=' + MAP_QUEST_KEY + '&inFormat=json&json=';
var CSV_FILE_NAME = 'smaller_stores.csv';
var inFile = path.join(__dirname, 'input', CSV_FILE_NAME);
var outFile = path.join(__dirname, 'output', CSV_FILE_NAME);
// create a location object
var createLocationJSONStream = function (data) {
var location = {
street: data.street_no + ' ' + data.street_name,
city: data.city_name,
state: data.state_id
};
var url = MAP_QUEST_URL + JSON.stringify(location);
// this request finishes after stream
request({
url: 'url',
method: 'GET',
json: location
}, function (error, response, body) {
if (error) {
console.log(error);
} else {
// get the latLng position so we can use it in our streaming
var position = body.results[0].locations[0].latLng;
var readFileStream = fs.createReadStream(inFile);
var writeFileStream = fs.createWriteStream(outFile);
var parseCsvStream = csv.parse({
trim: true,
headers: true,
objectMode: false
});
var deserializeJSONStream = JSONStream.parse();
var streamingEvent = readFileStream.pipe(parseCsvStream).transform(createLocationJSONStream).pipe(deserializeJSONStream);
// eventually want to write out to csv
//.pipe(csv.createWriteStream({headers: true}))
//.pipe(fs.createWriteStream(outFile, {encoding: 'utf8'}));
streamingEvent.on('data', function (data) {
console.log(JSON.stringify(data));
});
streamingEvent.on('end', function () {
console.log('end');
});
}
});
};
操作,那么他们会去哪里你做你的流:
position
latLng坐标现在可以在流代码中的任意位置的private String url = "http://www.hiddenlink.com/%s";
变量中使用,并且在数据准备就绪之前,您的流操作不会启动。
仅供参考,我发现如果使用promises而不是普通的回调,任何涉及多个异步操作的代码最终都更容易编写,理解并执行强大的错误处理。这需要了解承诺是如何运作的,并且经常涉及“承诺”#34;一些操作(将常规异步操作转换为返回promise的操作)。所以,从长远来看,我建议你开始学习承诺。我使用Bluebird promise库进行node.js开发,因为它有很多有用的功能。