我使用节点从其他网站请求应用详细信息,但我面临的问题是,它发送了数百(或几千)个请求,然后我收到错误,我什么都没收到。< / p>
阅读代码中的评论信息......
// I'm reading links from another file using 'fs'
fs.readFile('./google_apps/GAME_ACTION.json', 'utf8', function (err, data) {
if (err) throw err;
obj = JSON.parse(data);
// creating a empty array
var promiseStack = [];
for (var index in obj['GAME_ACTION']) {
var linksArray = obj['GAME_ACTION'][index];
linksArray.forEach( function(link, index) {
var appID = link.match(/id=.*/g)
var instr = appID.toString();
var appIDSliced = instr.slice(3)
// Here appIDSliced is ID, which is sliced from a link
// there are thousands on link in this file which I opened
console.log('sending') // for testing purpose
// here i'm pushing promises into that empty array
// store.app({id: appIDSliced}) is a promise I guess because I can use .then() on it...
// and store.app sends request to another website from which it receives an object in return.
// (Variable store is from another file 'require()' above in my node app fie )
promiseStack.push( store.app({id: appIDSliced}))
});
}
// After pushing all promises into array, now i'm trying to resolve them using Promise.all
Promise.all(promiseStack).then((responses) => {
console.log("Dealing with responses")
// Dealing with response (which is an object coming)
responses.map(response => {
var title = response.title
var package_name = response.appId
var appCategory = response.primaryGenre
var appSize = parseFloat((response.size/1024)/1024).toFixed(2)
var developerName = response.developer
var developerWebsite = response.developerWebsite
if (typeof developerWebsite == 'undefined') {
developerWebsite = "N/A"
}
var appPrice = response.price
var lastUpdated = response.updated
var contentRating = response.contentRating
if (typeof contentRating == 'undefined') {
contentRating = "N/A"
}
var userRating = response.score
if (typeof userRating == 'undefined') {
userRating = "N/A"
}
var dataRow = [appID, title, package_name, appCategory, appSize, developerName, developerWebsite, appPrice, lastUpdated, contentRating, userRating]
var dataToAdd = [dataRow];
console.log("Appending now")
// here i'm using google API to append that into my sheet on google
authentication.authenticate().then((auth)=>{
appendData(auth, dataToAdd);
});
})
})
})
请参见下图...这些是我在控制台上收到的错误 它不断记录和发送&#39;喜欢80秒,然后我得到错误&#34; UnhandledPromiseRejectionWarning&#34;在那里我被卡住了2分钟而且我一直按着“CTRL + C&#39;”。
感谢。
答案 0 :(得分:1)
async.each可能更合适,请查看async.each
Promise.all()在这种情况下看起来并不正确,因为方法返回一个Promise,它在iterable参数中的所有promise都已解析或者iterable参数不包含promise时解析。它拒绝承认拒绝的第一个承诺。 promise.all
我试图用异步重写你的代码,我做的假设很少,这是你可能会根据逻辑调整它的一般例子。
var async = require('async');
fs.readFile('./google_apps/GAME_ACTION.json', 'utf8', function (err, data) {
if (err) throw err;
var obj = JSON.parse(data);
async.each(obj['GAME_ACTION'], function(linksArray, callback){
linksArray.forEach( function(link,) {
var appID = link.match(/id=.*/g);
var instr = appID.toString();
var appIDSliced = instr.slice(3);
console.log('sending') // for testing purpose
// I am assuming that store.app() is asyncronous and get a callback
store.app({id: appIDSliced}, function(err, response){
if (err){
console.log('something bad happend');
callback();
}
else{
var title = response.title;
var package_name = response.appId;
var appCategory = response.primaryGenre;
var appSize = parseFloat((response.size/1024)/1024).toFixed(2);
var developerName = response.developer;
var developerWebsite = response.developerWebsite;
if (typeof developerWebsite == 'undefined') {
developerWebsite = "N/A"
}
var appPrice = response.price;
var lastUpdated = response.updated;
var contentRating = response.contentRating;
if (typeof contentRating == 'undefined') {
contentRating = "N/A"
}
var userRating = response.score;
if (typeof userRating == 'undefined') {
userRating = "N/A"
}
var dataRow = [appID, title, package_name, appCategory, appSize, developerName, developerWebsite, appPrice, lastUpdated, contentRating, userRating]
var dataToAdd = [dataRow];
console.log("Appending now");
authentication.authenticate().then((auth)=>{
appendData(auth, dataToAdd);
});
callback();
}
});
});
}, function (err) {
});
});
答案 1 :(得分:0)
您可以使用伪递归方法慢慢迭代一个又一个请求:
CREATE TABLE #SampleData
(
Name varchar(10),
Location varchar(20),
Item varchar(10),
Date varchar(8)
)
INSERT INTO #SampleData
VALUES
('Ron', 'Loc A', 'Pencil', '20170610'),
('Ron', 'Loc A', 'Pencil', '20170611'),
('Ron', 'Loc B', 'Pen', '20170610'),
('Ron', 'Loc B', 'Laptop', '20170611'),
('Tom', 'Loc A', 'Pencil', '20170611'),
('Tom', 'Loc B', 'Pencil', '20170610'),
('Tom', 'Loc B', 'Pen', '20170610'),
('Tom', 'Loc A', 'Pencil', '20170610'),
('Tom', 'Loc A', 'Laptop', '20170610'),
('Tom', 'Loc A', 'Pencil', '20170610')
DECLARE @Pivot_Columns AS VARCHAR(MAX),
@select_Columns VARCHAR(max)
SELECT @Pivot_Columns = Stuff((SELECT DISTINCT ',' + Quotename(Item) FROM #SampleData FOR xml path('')), 1, 1, '')
SELECT @select_Columns = Stuff((SELECT DISTINCT ',Sum(' + Quotename(Item) + ') as '+Quotename(Item) FROM #SampleData FOR xml path('')), 1, 1, '')
DECLARE @SQL AS VARCHAR(MAX)
SET @SQL = 'SELECT case when grouping(location) = 1 and grouping(name) = 0 then ''Total''+ '' '' + name
when grouping(location) = 1 and grouping(name) = 1 then ''Total''
else name end Name,
case when grouping(location) = 1 and grouping(name) = 0 then CONVERT(varchar(10), COUNT(Distinct location ))
when grouping(location) = 1 and grouping(name) = 1 then CONVERT(varchar(10), COUNT(Distinct location ))
else Location end Location,
'+ @select_Columns + '
FROM
(
SELECT name, location, item
FROM #SampleData
) as PivotData
PIVOT
(
count(item)
for item IN ('
+ @Pivot_Columns + ')
) AS PivotResult
group by name,location with rollup
'
EXEC(@SQL)
答案 2 :(得分:0)
for loop
当您推动store.app({id: appIDSliced})
&amp;我猜它开始以突发模式请求服务器。
Promise.all
正在解决陷入困境的请求。
为什么不运行n numbers at a time
并让它们关注直到所有服务器请求都完成。这样,大多数请求之间都会有延迟,因为在任何时候都会有最多5个请求运行而不是突发执行。
var functions = [];
var m;
for (var i = 0; i < 100; i++) {
(function(j) {
functions.push(function(callback) {
var random = Math.floor(Math.random() * 10000) + 1;
var s = document.getElementById('here');
var d = document.createElement('div');
d.innerHTML = 'function : ' + j + ' executed after :' + random;
s.appendChild(d);
setTimeout(callback, random);
// the above code executes something like xhr. remove it
// here you can write your own statements
// store.app({id: appIDSliced}, (err, response) => {
// responses.map(response => {
// var title = response.title
// {...}
// here i'm using google API to append that into my sheet on google
// authentication.authenticate().then((auth)=>{
// appendData(auth, dataToAdd);
// });
// });
// callback(); // you can add callback here after all your statements execution
// });
});
})(i);
}
function exec(method) {
// here method will call the below function which is in your case promise.
// function(callback) {
// console.log(j);
// callback();
// }
method(function() {
if (functions.length > m) {
exec(functions[m]);
m++;
}
});
}
// lets start only 5 at a time.
// first to complete next to start
// function number: 1 2 3 4 5
// completes : 2nd 3rd 1st 5th 4th
// start new : 7 8 6 10 9
setTimeout(function() {
for (m = 0; m < 5; m++) {
(function(m) {
exec(functions[m]); // this will execute 1,2,3,4,5 function
m++;
})(m);
}
}, 0);
&#13;
<div id="here"></div>
&#13;
答案 3 :(得分:0)
var Promise = require('bluebird');
function fetchData(objekt){
return new Promise((resolve, reject) => {
// api call and then
resolve(data);
})
}
function doRequest(){
Promise.coroutine(function *(){
yield Promise.map(arr, fetchData);
})()
.catch(err => {
console.error(err);
})
}
一个简单而短的代码,带有错误处理。