在nodeschool上学习时遇到的问题:learnyounode里的第九题:
写一个小程序,要求输入三个参数url,使用该程序模拟三次get请求分别从这三个url获取数据,全部返回后打印到控制台上。要求:打印出的响应数据要和三个url参数的顺序一样,即打印出的第一条应该是第一个url返回的数据,url由命令行参数提供(process.argv)。
因为node是异步的,所以不知道应该如何控制这个输出的顺序,求帮忙!
在nodeschool上学习时遇到的问题:learnyounode里的第九题:
写一个小程序,要求输入三个参数url,使用该程序模拟三次get请求分别从这三个url获取数据,全部返回后打印到控制台上。要求:打印出的响应数据要和三个url参数的顺序一样,即打印出的第一条应该是第一个url返回的数据,url由命令行参数提供(process.argv)。
因为node是异步的,所以不知道应该如何控制这个输出的顺序,求帮忙!
楼主可以使用这个异步库[async][1]
var async = require('async');
var http = require('http');
var urls = ['www.baidu.com', 'www.qq.com', 'www.haosou.com']
async.map(urls, function (url, callback) {
var data = "";
http.get({host: url}, function (res) {
res.setEncoding('utf-8');
res.on('data', function (chunck) {
data += chunck;
});
res.on('end', function () {
callback(null, data);
});
}).on('error', function (error) {
return callback(error);
});
}, function(error, result){
if(error)
console.log(error);
else
console.log(result)
})
一般以前我碰上这种情况都会果断的选择回调来写的,代码大概是下面这个样子:
var http = require("http"),
urls = process.argv,
datas = [];
if( urls.shift() === "node" ) urls.shift();
function getHTML( url, callback ) {
http.get( url, function( res ) {
var result = "";
res.on( "data", function(chunk) { result += chunk; })
.on( "end", function() { callback( result ); });
})
}
(function get( p ) {
if( p === urls.length ) return last();
getHTML( urls[p], function(res) {
datas.push( res )
get( ++p );
})
function last() {
datas.forEach(function(d){ console.log(d) })
}
})(0);
但是自从接触了 Promise 之后感觉这样写异步要顺畅多了,所以慢慢的也转变过来了,代码大概是这个样子的:
var Promise = require("promise").Promise,
http = require("http");
var urls = process.argv;
if( urls.shift() === "node" ) urls.shift();
function getHTML( url ) {
return new Promise(function( resolve, reject ) {
http.get( url, function( res ) {
var result = "";
res.on( "data", function(chunk) { result += chunk })
.on( "end", function() { resolve(result) })
.on( "error", function() { reject(result) })
})
})
}
urls.map(getHTML).reduce(function(seq, html) {
return seq.then(function(){return html}).then(function(res){
console.log( res );
})
}, Promise.resolve());
3 回答2.8k 阅读✓ 已解决
1 回答1.1k 阅读✓ 已解决
1 回答1.3k 阅读✓ 已解决
2 回答758 阅读✓ 已解决
2 回答1.8k 阅读
2 回答844 阅读✓ 已解决
2 回答1.3k 阅读
原生版,用results和counter两个变量维护状态,保持顺序靠那个idx变量实现
能够完成需求,但容错、扩展、可读性一塌糊涂
request+bluebird版
题目没说并行请求还是串行,这里都是并行的,串行的话反正天然保持顺序闭着眼睛打印就行