I've got the following jQuery code which I use in a Bookmarklet. It clicks on all the buttons on the page (with the class "Unfollow") one by one, with a random time between each one...
javascript: (function() { var unfollowButtons = $('button.Unfollow'); var index = unfollowButtons.length - 1; unfollow(); function unfollow() { if (index >= 0) { $(unfollowButtons[index--]) .click(); setTimeout(unfollow, Math.floor((Math.random() * 1000) + 500)); } } })();
I'd like to run the above function again twice once it has completed its cycle.
Just running the function again causes that to run in parallel with the first function call.
How do I run the unfollow() function 2 or 3 times without them all running in parallel?
11 Answers
Answers 1
Try it this way (using ES6 Promises):
var runUnfollow = function() { return new Promise(function(resolve, reject){ var index = unfollowButtons.length - 1; // fencepost for the loop var p = Promise.resolve(); // we stop execution at `i == 0` for (var i = index; i >= 0; i--) { // run the promise // then set `p` as the next one p = p.then(unfollowTimeout.bind(null, i)); } // make sure we run the last execution at `i == 0`. p.then(function(){ resolve(); }) function unfollowTimeout(i){ // return a promise to run `unfollow` and a `setTimeout` return new Promise(function(resolve,reject){ unfollow(i); setTimeout(resolve, Math.floor((Math.random() * 1000) + 500)); }) } function unfollow(i) { $(unfollowButtons[i]) .click(); } }) } // run three times synchronously runUnfollow().then(runUnfollow).then(runUnfollow).then(function(){ //finished }); // another way to run three times synchronously p = runUnfollow(); for(i=3; i > 0; i--){ p.then(runUnfollow); } p.then(function(){ //finished }); // run in parallel Promise.all([runUnfollow, runUnfollow, runUnfollow]) .then(function(){ //finished });
EDIT: Went back and read your question again, realized you were trying to run everything multiple times. I've edited to reflect that.
Answers 2
Just reset index
and restart after each button is clicked:
javascript: (function() { var unfollowButtons = $('button.Unfollow'); var index = unfollowButtons.length - 1; var totalRuns = 3; unfollow(); function unfollow() { if (index < 0 && totalRuns) { totalRuns--; index = unfollowButtons.length - 1; } if (index >= 0) { $(unfollowButtons[index--]) .click(); setTimeout(unfollow, Math.floor((Math.random() * 1000) + 500)); } } })();
Answers 3
You should look at Promises
.
Resolve your Promise
at your function's execution's very end and call your function again. You should be good with that.
Answers 4
In your specific case, you could simply build an array which contains twice each button :
// turn the jQuery selection into a regular array : var unfollowButtons = $('button.Unfollow').get(); // build a new array, which contains two copies of the above selection : unfollowButtons = unfollowButtons.concat(unfollowButtons);
Answers 5
You have 2 options
1.Use a User Script
For that, you need a User Script extension manager, for example Tampermonkey for Chrome, Greasemonkey for Firefox, etc.
But since you want a bookmarklet, just leave it.
2.Modify the Bookmarklet a little as follows
Add this code inside the unfollow
function
That is check whether index
reached 0 and also the flag is set or not.
FLAG
is important otherwise it will create a infinitive recursion loop.
First set FLAG
to 0 outside of unfollow
function.
Then in unfollow
function, if the FLAG
is 0 and index
is 0, initiate the next iteration and Set FLAG
to 1.
if(index < 0 && FLAG==0){ var unfollowButtons = $('button.Unfollow'); FLAG=1; var index = unfollowButtons.length - 1; unfollow(); }
So, it will look like this.
javascript: (function() { var unfollowButtons = $('button.Unfollow'); var index = unfollowButtons.length - 1; var FLAG=0; unfollow(); function unfollow() { if (index >= 0) { $(unfollowButtons[index--]) .click(); if(index < 0 && FLAG==0){ unfollowButtons = $('button.Unfollow'); FLAG=1; index = unfollowButtons.length - 1; unfollow(); } setTimeout(unfollow, Math.floor((Math.random() * 1000) + 500)); } } })();
If you want to do it totally 3 times, change if(index < 0 && FLAG<=2){
and FLAG=1
to FLAG +=1
Answers 6
As i understand your requirements it can be done like this :
javascript: (function() { var unfollowButtons = $('button.Unfollow'); var index = unfollowButtons.length - 1; unfollow(); var runForNoOfTime = 3; var runningForTime = 1; function unfollow() { if (index >= 0) { $(unfollowButtons[index--]).click(); setTimeout(unfollow, Math.floor(Math.random() * 1000) + 500)); }else if(runningForTime < runForNoOfTime){ runningForTime++; unfollowButtons = $('button.Unfollow'); //if buttons with class 'Unfollow' changes. index = unfollowButtons.length - 1; setTimeout(unfollow, Math.floor(Math.random() * 1000) + 500)); } } })();
Answers 7
You can use recursion to achieve the desired effect of running your function multiple times sequentially. Here's how this can be done:
(function() { var unfollowButtons = $('button.Unfollow'); var index = unfollowButtons.length - 1; function unfollow(callback) { if (index >= 0) { $(unfollowButtons[index--]).click(); } callback(); } function handleUnfollow(maxIter, iter) { iter = typeof iter === "number" ? iter : 0; if ( iter >= maxIter ) { // base case reached, stop further recursive calls return true; } // call unfollow once unfollow(function() { setTimeout(function() { // recursive call handleUnfollow(maxIter, ++iter); }, Math.floor((Math.random() * 1000) + 500)); }); } // execute recursive function, which will iterate 2 times handleUnfollow(2); })();
Answers 8
As far as I'm aware Javascript runs on a single thread, so there is no actual parallel processing taking place.
If you just simply want the function to run itself x times then use recursion:
function DoSomething(steps) { // Do stuff here steps--; if (steps <== 0) { return; } DoSomething(steps); }
If you want things to run in "parallel" with Javascript then perhaps you could look into having some external code that manages threads and executes multiple Javascript processes in parallel (although I'm not sure if this is possible, and, if it is, whether you'll be able to have the scripts accessing the same data at the same time or talking to eachother).
Answers 9
I have made the current code as block and added wrapper logic. Check if this works.
(function() { var iterations = 2; unfollowBlock(); function unFollowBlock() { if (iterations-- >0) { var unfollowButtons = $('button.Unfollow'); var index = unfollowButtons.length - 1; unfollow(); function unfollow() { if (index >= 0) { $(unfollowButtons[index--]) .click(); setTimeout(unfollow, Math.floor((Math.random() * 1000) + 500)); } else { //index=-1 end of unfollowblock setTimeout(unFollowBlock, Math.floor((Math.random() * 1000) + 500)); } } } } })();
Answers 10
Declare a flag/check variable eg. var isCycleComplete;
var isCycleComplete = false; if(isCycleComplete){ // if true runs unfollow function twice if cycle is completet unfollow(); unfollow(); isCycleComplete = false; // resets flag } else{ // if false unfollow(); isCycleComplete = true; //sets flag to true }
M not a pro at javascript but See if this simple snippet helps you.
Answers 11
function DoSomething(steps) { // Do stuff here steps--; if (steps < == 0) { return; } DoSomething(steps); }
try this hope it will be useful.
0 comments:
Post a Comment