var urlArr = {
//ex url_for_site0 = 'https://www.google.com'
url_for_site0,
url_for_site1,
url_for_site2,
url_for_site3,
...
url_for_site50
};
urlArr.forEach(function(url, index) {
request(url, function(err, res, body) {
if(err) console.log(index+err);
else console.log(index+" success");
});
});
每次执行我的应用时,我都会得到不同的无序结果和错误。
示例:
1 error : socket hang out
21 error : socket hang out
17 error : socket hang out
1 error : socket hang out
19 error : socket hang out
...(omission)
5 success
15 success
45 success
50 success
11 success
37 success
每当我得到结果时,它们的顺序都不同。 这是因为我同时打了太多请求吗? 当我逐个请求时,没有错误。
示例:
request(url_for_site0)
and restart program
request(url_for_site1)
and restart program
request(url_for_site2)
...
答案 0 :(得分:1)
NodeJS事件都在一个池中处理,并且具有非阻塞性质。您可以参考下图。
当我尝试调用多个SQL查询时,它发生在我身上。当我使用C#完成它时,根本没有问题。但是,NodeJS给了我类似的行为。
我不确定这是否是问题的最佳解决方案。但是,这是我如何解决我的SQL调用问题。我使用了异步瀑布函数,以便整个过程变得同步。每个函数将逐个运行,其返回值通过管道传递给下一个函数。所以,你甚至可以做更多的事情。这个库的用法不是很明确,您可以参考此链接以更好地帮助您了解异步瀑布的工作原理,然后使其适合您的解决方案。
https://gist.github.com/dineshsprabu/e6c1cf8f2ca100a8f5ae
以下是我将您的解决方案可视化的方式大致如下:
var async = require('async');
async.waterfall(
[
function(callback) {
function_urlArr(url, index, function (returnVal) {
//Do something with the returnVal
callback(null, returnVal);
});
},
function(returnVal, callback) {
//the returnVal from first function gets passed here synchronously
function_urlArr(url2, index2, function (returnVal) {
//Do something with the returnVal
callback(null, returnVal);
});
},
function(returnVal, callback) {
//and so on ...
}
],
function (err) {
//console.log(err);
});
//define your function and enable callback
//you will need to include an extra third argument to receive the callback
function urlArr(url, index, callback) {
//your code
return callback(returnValue)
}
答案 1 :(得分:0)
答案 2 :(得分:0)
You might have issue with non-blocking nature of loop forEach
.
You can combine Promise
and aysnc/await
to make it blocking. Here is one way of handling it.
const request = require('request');
let urlArr = [
'https://localhost:9090',
'https://www.google.com',
'https://www.ebay.com',
'https://www.amazon.com',
];
//Creating promise for the requests.
let fetchPromise = function(url) {
return new Promise((resolve, reject) => {
request(url, (err, res, body) => {
if (err)
reject(Error(url + ' cannot be fetched'));
else
resolve(body);
});
}
);
};
//creating a blocking function
let fetchAllData = async function(urls) {
for (url of urls) { //using modern for loop instead for forEach
try {
data = await fetchPromise(url); // waiting until promise is resolved.
console.log('Recieved :' + data.length + 'bytes from ' + url);
} catch(e) {
console.log('Error :' + e); // catching error in case promise is rejected
}
}
};
//calling the function
fetchAllData(urlArr);
/*
// In case you want to wait until all promises are resolved.
// Then use Promise.all, however it will fail if any of the promise is rejected.
// One way to handle it would be to modify function fetchPromise such that it
// always resolves.
Promise
.all(urlArr.map(url => fetchPromise(url)))
.then(data => console.log(data))
.catch(err => console.log(err));
*/
I hope it helps.