http请求方法中的callback – 没有按正确的顺序发生

我写了一个程序,为三个不同的URL做HTTP GET请求。 程序应该按照提供URL的顺序输出消息正文,但是即使我按照正确的顺序进行callback,它也不会这样做。

最终的程序应该要求用户通过命令行inputURL,但是我只是简单地做了variables赋值以便于testing。

我意识到这个代码可能更面向对象 – 但是我是JavaScript新手,并不是我目前学习的重点

var http = require('http') // var url_1 = process.argv[2] // var url_2 = process.argv[3] // var url_3 = process.argv[4] var url_1 = 'http://youvegotmail.warnerbros.com/cmp/0frameset.html' var url_2 = 'http://www.3riversstadium.com/index2.html' var url_3 = 'http://toastytech.com/evil/' var output_1 = '' var output_2 = '' var output_3 = '' function getHttp_1 (callback) { http.get(url_1, function getResponse (response1) { response1.setEncoding('utf8') response1.on('data', function (data) { output_1 = output_1 + data }) response1.on('end', function processData() { console.log("Printing Result 1:") callback(output_1) }) }) } function getHttp_2 (callback) { http.get(url_2, function getResponse (response2) { response2.setEncoding('utf8') response2.on('data', function (data) { output_2 = output_2 + data }) response2.on('end', function processData() { console.log("Printing Result 2:") callback(output_2) }) }) } function getHttp_3 (callback) { http.get(url_3, function getResponse (response3) { response3.setEncoding('utf8') response3.on('data', function (data) { output_3 = output_3 + data }) response3.on('end', function processData() { console.log("Printing Result 3:") callback(output_3) }) }) } function printResults(output) { console.log("Result") // console.log(output) } getHttp_1(printResults) getHttp_2(printResults) getHttp_3(printResults) 

编辑:

结果我一般会得到:

 Printing Result 3: Result Printing Result 2: Result Printing Result 1: Result 

结果我期待:

 Printing Result 1: Result Printing Result 2: Result Printing Result 3: Result 

欢迎来到node.js的asynchronous生活! 当你启动这些HTTP请求时,在启动之前不会等待请求完成。 你看到这种奇怪的行为,因为你实际上一次发送所有3个请求,而只是打印,因为你看到的答复。

编辑:如果你想看到他们正确的顺序,发射第一个callback里面的第二个HTTP请求,然后在第二个callback里面的第三个HTTP请求。 这保证你在每次完成之前都不会得到数据。

 function getHttp_1 (callback) { http.get(url_1, function getResponse (response1) { response1.setEncoding('utf8') response1.on('data', function (data) { output_1 = output_1 + data }) response1.on('end', function processData() { console.log("Printing Result 1:") callback(output_1) getHttp_2(callback) }) }) } 

与一些答案提出的顺序callback方法相反,使用Promise将使这个更有效率(请求将并行)和更简单:

 var http = require('http'), urls = [ 'http://youvegotmail.warnerbros.com/cmp/0frameset.html', 'http://www.3riversstadium.com/index2.html', 'http://toastytech.com/evil/' ]; Promise.all(urls.map(getUrl)) .then(function (results) { results.forEach(function (output, i) { console.log("Result #" + (i + 1) + " with length: " + output.length); }); }); function getUrl(url, i) { return new Promise(function (resolve, reject) { http.get(url, function getResponse(resp) { var output = ''; resp.setEncoding('utf8'); resp.on('data', function (data) { output += data; }); resp.on('end', function processData() { console.log("Resolving Result " + (i + 1) + ":"); resolve(output); }); }) }); } 

asynchronous模块可以真正帮助控制如何执行asynchronous任务。 例如,如果您希望您的请求一个接一个地发生:

 async.series([ function (next) { makeRequest(url_1, next); }, function (next) { makeRequest(url_2, next); }, function (next) { makeRequest(url_3, next); }, ], function (err, result) { // All done }); // Or you can get fancy //async.series([ // makeRequest.bind(null, url_1), // makeRequest.bind(null, url_2), // makeRequest.bind(null, url_3), //]); function makeRequest(url, callback) { http.get(url, function getResponse (res) { var output = ''; res.setEncoding('utf8') res.on('data', function (data) { output += data }) response1.on('end', function processData() { callback(output) }) }) } 

如果你不关心它们发生的顺序,而是想按顺序输出它们:

 async.parallel([ function (next) { makeRequest(url_1, next); }, function (next) { makeRequest(url_2, next); }, function (next) { makeRequest(url_3, next); }, ], function (err, results) { if (err) { return void console.error('Got an error:', err.stack); } console.log(results); // Will output array of every result in order }); 

如果请求相互依赖, async.auto将一个请求的结果与另一个请求的结果联系async.auto是有用的。

JavaScript / AJAX调用是asynchronous的,所以不要按照你所说的顺序。 要按顺序/特定顺序调用它们,请执行以下操作:

 $(function () { //setup an array of AJAX options, each object is an index that will specify information for a single AJAX request var ajaxes = [{ url : '<url>', dataType : 'json' }, { url : '<url2>', dataType : 'utf8' }], current = 0; //declare your function to run AJAX requests function do_ajax() { //check to make sure there are more requests to make if (current < ajaxes.length) { //make the AJAX request with the given data from the `ajaxes` array of objects $.ajax({ url : ajaxes[current].url, dataType : ajaxes[current].dataType, success : function (serverResponse) { ... //increment the `current` counter and recursively call this function again current++; do_ajax(); } }); } } //run the AJAX function for the first time once `document.ready` fires do_ajax(); }); 

另一种select可能是:

 function callA() { $.ajax({ ... success: function() { //do stuff callB(); } }); } function callB() { $.ajax({ ... success: function() { //do stuff callC(); } }); } function callC() { $.ajax({ ... }); } callA(); 

参考: 订单多个电话