I have this javascript code that is meant to run inside the google chrome console. It constantly checks a json formatted response. If anywhere in the response BestPrice equals max_price then it will purchase it using some API. The problem I am having is about 10 seconds after running it I get 'ERR_INSUFFICIENT_RESOURCES'.
I suppose it is from too many requests? I need it to loop through as fast as possible, so if it can't be instant, is there a certain request limit?
Code:
function snipebot(page, max_page, max_price){
$.getJSON('http://www.roblox.com/catalog/json?browse.aspx?Subcategory=2&Keyword=&CurrencyType=0&pxMin=0&pxMax=0&SortType=2&SortAggregation=0&SortCurrency=0&LegendExpanded=true&Category=2&PageNumber=' + page, function(data){
$.each(data, function(index, item){
if (item['BestPrice'] <= max_price){
$.get('http://www.roblox.com/Item.aspx?id=' + item['AssetId'], function(data){
var purchaseData = $($(data).find(".PurchaseButton")[0]).data();
if (purchaseData['expectedPrice'] <= item['BestPrice']){
$.post('/API/Item.ashx?rqtype=purchase&productID=' + purchaseData['productId'] + '&expectedCurrency=1&expectedPrice=' + purchaseData['expectedPrice'] + '&expectedSellerId=' + purchaseData['expectedSellerId'] + '&userAssetID=' + purchaseData['userassetId'], function(){
console.log('[' + item['BestPrice'] + '] #' + new Date().toTimeString())
});
} else {
console.log("Detected purchase.");
}
});
};
setTimeout(function(){
snipebot(page + 1 > max_page ? 1 : page + 1, max_page, max_price);
},100);
console.log("!checked");
});
});
};
snipebot(1, 4, 50);
When you call snipebot, it makes a request, and looking at the URL you're using, it gets an array back. Then for each item in the array, you are spawning another snipebot call. Each of those calls would in turn spawn more snipebot calls and so on. So, yeah, the ERR_INSUFFICIENT_RESOURCES error isn't really surprising.
Related
I am currently working on fetching/scraping all the images being received on requesting a URL.
The problem i am facing is the response changes after few tries or is very inconsistent even for the same URL using the phantomjs.
I have tried clearing cache multiple times and at different location in my code but the the request numbers dont appear to be the same.
o/p
1st call to URL
19 images and total off 49 responses from server
2nd call
14 images and 48 responses from server
3rd call
14 images and 38 responses from server
Output for execution twice
phantomjs-2.1.1-windows
running a java-script code using the phantomjs command
I am very new to Javascript, i have manged to write the following till now
var page = require('webpage').create();
var fs = require('fs');
var url = "https://..........";
page.settings.clearMemoryCaches = true;
page.clearMemoryCache();
page.clearCookies();
page.viewportSize = {width: 1280, height: 1024};
var imageCounter = 0;
var responseCounter = 0;
page.open(url, function (status) {
console.log(status + '*/*/*/*/*/*/**/*/*/*/*/*/*/*/*/*/*/*/*/*/')
if(status=='success'){
console.log('The entire page is loaded.............################');
console.log('\n' + imageCounter + '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n');
console.log('\n' + responseCounter + '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n');
imageCounter = 0;
page.clearMemoryCache();
page.clearCookies();
page.close();
phantom.exit();
}
});
page.onResourceReceived = function(response) {
if(response.stage == "start"){
responseCounter++;
var respType = response.contentType;
if(respType.indexOf("image")==0){
imageCounter++;
//console.log('Content-Type : ' + response.contentType)
//console.log('Status : ' + response.status)
//console.log('Image Size in byte : ' + response.bodySize)
//console.log('Image Url : ' + response.url)
//console.log('\n');
console.log(imageCounter + '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n');
}
}
};
I want to get consistent response for the images at least, I am really confused how does phantom cache this kind of resources on second attempt.
I'm having difficulty juggling values in jQuery, as most of jQuery is done in an external script, and I'm not sure when I'm in functions and not in functions, so it's hard to tell when global vars are set and not set.
This one in particular is puzzling me, and I'm absolutely stumped, logically to me it should work, but there seems to be something capping it at some point, and disregarding the values I'm trying to store.
I've concluded this, as the error I'm having is that inside the second getJSON call, I'm getting a 'val' undefined issue, but Javascript console isn't showing any javascript errors, just getting an undefined log when I log to the console and also print the object in an alert.
Just need a fresh set of eyes, feel like this is probably something simple, but I've been looking at the code so long that I can't seem to fathom it.
Any help is greatly appreciated.
var post_ids = new Array();
var i = 0;
var val;
$.getJSON("/client-ajax/last-ten-posts.php", function(data){
$.each(data, function(k, val) {
post_ids.push(val.id);
});
});
$.getJSON("/client-ajax/last-ten-posts.php?post-id=" + post_ids[0], function(val){
alert(val.title+"");
$("#postContainer").empty();
$("#postContainer").append("<p class='title'>" + val.title + "</p><div class='post-icon'></div><pre>" + val.content + "</pre><p class='footnote'>Posted by " + val.firstname + " " + val.surname + " at <time datetime='2014-06-10'>08:52</time> GMT+00 on the <time>10-06-2014</time></p>");
});
UPDATE:
I edited the code slightly in light of #N0ir's answer, but to no success. The done method ensure that actions are taken once the async process is complete, but although this is the case, val is still undefined. The code I've tried is below for examination and dissemination.
$.getJSON("/client-ajax/last-ten-posts.php", function(data){
$.each(data, function(k, val) {
post_ids.push(val.id);
});
}).done(function(){
$.getJSON("/client-ajax/last-ten-posts.php?post-id=" + post_ids[0], function(val){
alert(val.title+"");
$("#postContainer").empty();
$("#postContainer").append("<p class='title'>" + val.title + "</p><div class='post-icon'></div><pre>" + val.content + "</pre><p class='footnote'>Posted by " + val.firstname + " " + val.surname + " at <time datetime='2014-06-10'>08:52</time> GMT+00 on the <time>10-06-2014</time></p>");
});
});
UPDATE - Network Return on call for JSON:
GET http://*****************.com/client-ajax/last-ten-posts.php [HTTP/1.1 200 OK 154ms]
GET http://*****************.com/img/home.jpg [HTTP/1.1 304 Not Modified 152ms]
GET http://*****************.com/img/about.png [HTTP/1.1 304 Not Modified 142ms]
GET http://*****************.com/img/about-repeat.jpg [HTTP/1.1 304 Not Modified 147ms]
GET http://*****************.com/img/blog.jpg [HTTP/1.1 304 Not Modified 146ms]
GET http://*****************.com/img/portfolio.jpg [HTTP/1.1 304 Not Modified 210ms]
GET http://*****************.com/img/contact.jpg [HTTP/1.1 304 Not Modified 209ms]
GET http://*****************.com/client-ajax/last-ten-posts.php [HTTP/1.1 200 OK 207ms]
You wanna do somethign like this:
var post_ids = new Array();
var i = 0;
var val;
$.getJSON("/client-ajax/last-ten-posts.php", function(data){
$.each(data, function(k, val) {
post_ids.push(val.id);
});
$.getJSON("/client-ajax/last-ten-posts.php?post-id=" + post_ids[0], function(result){
alert(result.title+"");
$("#postContainer").empty();
$("#postContainer").append("<p class='title'>" + result.title + "</p><div class='post-icon'></div><pre>" + result.content + "</pre><p class='footnote'>Posted by " + result.firstname + " " + result.surname + " at <time datetime='2014-06-10'>08:52</time> GMT+00 on the <time>10-06-2014</time></p>");
});
});
So that the second getJSON call happens after the first one is finished.
So I found the issue, turns out fetchAll() in php's PDO returns an array, so when creating the JSON from the array, the JSON needs to be accessed through the first element of the array, like so:
val[0].content
rather than:
val.content
I seem to have a memory leak in IE9. It works just fine in Chrome. The memory leak is on the client machine. I left this page open for days in chrome and no leak.
Using jquery 1.9.0, signalr rc2
This page uses signalr and refreshes it's contents every 5 seconds with what comes from the server.
I have four tabs/divs that do this.
proxy.on('newRequests', function (data, updatetime) {
newrequestupdatetime.text('Last updated: ' + updatetime);
numberofnewrequests.text('Number of cases found: ' + data.length);
numberofnewrequeststab.text('(' + data.length + ')');
var h = '';
$.each(data, function (i, val) { h += '<li>' + val.Ref + ' ' + val.Type + '</li>'; });
newrequests.html(h);
});
newrequests is an ul on the page which I initialized like this
var newrequests = $('#newrequests');
in
$(function () {});
Not really sure what is the cause.
I can make it a lot worse by doing this.
newrequests.empty();
$.each(data, function (i, val) { newrequests.append('<li>' + val.Ref + ' ' + val.Type + '</li>'); });
I'm guessing that it has something to do with the last line of code, that puts the new html inside the ul tag.
Try changing the line into this (old code):
document.getElementById('newrequests').innerHTML = h;
See also: jQuery - Internet Explorer memory leaks
I'm trying to get the last 50 tweets using a certain hash tag, on a mobile device using PhoneGap (0.9.6) and jQuery (1.6.1). Here's my code:
function getTweets(hash, numOfResults) {
var uri = "http://search.twitter.com/search.json?q=" + escape(hash) + "&callback=?&rpp=" + numOfResults;
console.log("uri: " + uri);
$.getJSON(uri, function(data) {
var items = [];
if(data.results.length > 0) {
console.log("got " + data.results.length + " results");
$.each(data.results, function(key, val) {
var item = "<li>";
item += "<img width='48px' height='48px' src='" + val.profile_image_url + "' />";
item += "<div class='tweet'><span class='author'>" + val.from_user + "</span>";
item += "<span class='tweettext'>" + val.text + "</span>";
item += "</div>";
item += "</li>";
items.push(item);
});
}
else {
console.log("no results found for " + hash);
items.push("<li>No Tweets about " + hash + " yet</li>");
}
$("#tweetresults").html($('<ul />', {html: items.join('')}));
});
}
This code works great in a browser, and for a while worked in the iPhone simulator. Now it's not working on either the iPhone or Android simulator. I do not see any of the console logs and it still works in a browser.
What am I doing wrong? If it's not possible to call getJson() on a mobile device using PhoneGap, what is my alternative (hopefully without resorting to native code - that would beat the purpose).
Bonus: how can I debug this on a mobile simulator? In a browser I use the dev tools or Firebug, but in the simulators, as mentioned, I don't even get the log messages.
As always, thanks for your time,
Guy
Update:
As #Greg intuited, the function wasn't called at all. Here's what I found and how I bypassed it:
I have this <a> element in the HTML Get tweets
Then I have this code in the $(document).ready() function:
$("#getTweets").click(function() {
var hash = "#bla";
getTweets(hash, 50);
});
That didn't call the function. But once I changed the code to:
function gt() {
var hash = "#bla";
getTweets(hash, 50);
}
and my HTML to:
Get Tweets
it now works and calls Twitter as intended. I have no idea what's screwed up with that particular click() binding, but I ran into similar issues with PhoneGap before. Any ideas are appreciated.
Considering that (a) there isn't much that could go wrong with the first line of your function and (b) the second line is a log command, then it would seem that the function isn't being called at all. You'll have to investigate the other code in your app.
Or are you saying that you don't have a way to read logged messages on your mobile devices?
I'm sure I've seen this before and know the answer to it but after 12 hours... my mind is complete mush.
I have a for loop in which I am trying to concatenate onto a string so that AFTER I can complete the string (thus completing a nice little table) that I had hoped to then insert into my html and show the user.
However, the things at the end of my function (after my for loop) are getting called before the for loop ever does....
function getEntries() {
$('#entryTotalsDiv').html('<img src="images/ajax-loader.gif" /> ... retrieving form totals.');
var entryTotalsTable = "<table id='entryTable' class='display' style='border:1px;'><thead><tr><th>Form Name</th><th>Hash</th><th>Entries</th></tr></thead>" +
"<tbody>"
//Get rows ONE at a time.
var countNumber = 1;
for (var frm = 0; frm < numberOfForms; frm++) {
$.post('ajax/getEntries.aspx',
{
'formNumber': frm
},
function (data) {
entryTotalsTable += "<tr><td>" + data[0].formName + "</td><td>" + data[0].formHash + "</td><td>" + data[0].formEntryCount + "</td></tr>";
//Now go and update the Form Retrieval div -- add 1 to the frm Number
$('#formNamesDiv').html(countNumber + ' of ' + numberOfForms + ' retrieved.');
countNumber++;
});
}
entryTotalsTable += "</tbody></table>";
$('#entriesDiv').html(entryTotalsTable);
//Now bind the table to the DataTables JQ script
$('#entryTable').dataTable();
$('#entryTable').show('slow');
}
If you notice, I wanted to close up the Table html at the end, but this gets called before my for loop is finished, thus screwing up my string...
?
entryTotalsTable += "</tbody></table>";
$('#entriesDiv').html(entryTotalsTable);
//Now bind the table to the DataTables JQ script
$('#entryTable').dataTable();
$('#entryTable').show('slow');
}
A solution could be to save every response in an array and test in every callback whether the current count is equal to the total count. Something like:
var countNumber = 1,
allData = [];
function runWhenFinished() {
if(countNumber === numberOfForms) {
var entryTotalsTable = "<table id='entryTable' class='display' style='border:1px;'><thead><tr><th>Form Name</th><th>Hash</th><th>Entries</th></tr></thead>" + "<tbody>";
for(var i = 0, l = allData.length; i < l; i++) {
entryTotalsTable += "<tr><td>" + allData[i].formName + "</td><td>" + allData[i].formHash + "</td><td>" + allData[i].formEntryCount + "</td></tr>";
}
entryTotalsTable += "</tbody></table>";
$('#entriesDiv').html(entryTotalsTable);
//Now bind the table to the DataTables JQ script
$('#entryTable').dataTable();
$('#entryTable').show('slow');
}
}
for(var frm = 0; frm < numberOfForms; frm++) {
(function(frm) {
$.post('ajax/getEntries.aspx',{'formNumber': frm}, function (data) {
allData[frm] = data[0];
countNumber++;
$('#formNamesDiv').html(countNumber + ' of ' + numberOfForms + ' retrieved.');
runWhenFinished();
});
}(frm));
}
I'm sure this can still be improved, but you get the idea.
If you really make 70 requests then you might want to rethink your strategy anyway. 70 simultaneous requests is a lot.
E.g. you could make one request and prove the minimum and maximum number of that should be retrieved / updated / whatever the method is doing.
$.post is asynchronous, meaning that it's firing off all the requests in the loop as fast as it can, and then exiting the loop. It doesn't wait for a response. When the response comes back, your row function is then called... but by then, all the posts have been sent on their way.
See the answers to this question here...
How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?
You'll need to change from $.post to $.ajax