[英]Running a jQuery function multiple times sequentially (for a Bookmarklet)
我在 Bookmarklet 中使用了以下 jQuery 代碼。 它逐個點擊頁面上的所有按鈕(帶有“取消關注”類),每個按鈕之間有一個隨機時間......
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));
}
}
})();
一旦完成循環,我想再次運行上述函數兩次。
再次運行該函數會導致它與第一個函數調用並行運行。
如何在不並行運行的情況下運行 unfollow() 函數 2 或 3 次?
以這種方式嘗試(使用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 = p.then(runUnfollow);
}
p.then(function(){
//finished
});
// run in parallel
Promise.all([runUnfollow, runUnfollow, runUnfollow])
.then(function(){
//finished
});
編輯:返回並再次閱讀您的問題,意識到您正在嘗試多次運行所有內容。 我已經編輯以反映這一點。
只需在單擊每個按鈕后重置index
並重新啟動:
javascript: (function() {
var unfollowButtons = $('button.Unfollow');
var index = unfollowButtons.length - 1;
var totalRuns = 3;
unfollow();
function unfollow() {
if (index < 0 && totalRuns) {
totalRuns--;
unfollowButtons = $('button.Unfollow');
index = unfollowButtons.length - 1;
}
if (index >= 0) {
$(unfollowButtons[index--])
.click();
setTimeout(unfollow, Math.floor((Math.random() * 1000) + 500));
}
}
})();
你應該看看Promises
。
在函數執行的最后解析你的Promise
並再次調用你的函數。 你應該很擅長這個。
你有2個選擇
為此,您需要一個用戶腳本擴展管理器,例如 Chrome 的 Tampermonkey、Firefox 的 Greasemonkey 等。
但既然你想要一個書簽,就留下吧。
在unfollow
功能中添加此代碼
即檢查index
是否達到 0 以及是否設置了標志。
FLAG
很重要,否則它會創建一個不定式遞歸循環。
首先在unfollow
功能之外將FLAG
設置為 0。
然后在unfollow
函數中,如果FLAG
為 0, index
為 0,則啟動下一次迭代並將FLAG
設置為 1。
if(index < 0 && FLAG==0){
var unfollowButtons = $('button.Unfollow');
FLAG=1;
var index = unfollowButtons.length - 1;
unfollow();
}
所以,它看起來像這樣。
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));
}
}
})();
如果你想總共做 3 次, if(index < 0 && FLAG<=2){
和FLAG=1
更改為FLAG +=1
在您的特定情況下,您可以簡單地構建一個數組,其中每個按鈕包含兩次:
// 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);
據我了解您的要求,可以這樣做:
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));
}
}
})();
您可以使用遞歸來實現按順序多次運行您的函數的預期效果。 這是如何做到的:
(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);
})();
據我所知 Javascript 在單個線程上運行,因此沒有發生實際的並行處理。
如果你只是想讓函數自己運行 x 次,那么使用遞歸:
function DoSomething(steps) {
// Do stuff here
steps--;
if (steps <== 0) {
return;
}
DoSomething(steps);
}
如果您希望事情與 Javascript 以“並行”運行,那么也許您可以考慮使用一些外部代碼來管理線程並並行執行多個 Javascript 進程(盡管我不確定這是否可行,如果是,您是否能夠讓腳本同時訪問相同的數據或相互交談)。
我將當前代碼作為塊並添加了包裝器邏輯。 檢查這是否有效。
(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)); } } } } })();
聲明一個標志/檢查變量,例如。 var isCycleComplete;
var isCycleComplete = false;
if(isCycleComplete){ // if true runs unfollow function twice
unfollow();
unfollow();
isCycleComplete = false; // resets flag
}
else{ // if false
unfollow();
isCycleComplete = true; //sets flag to true
}
我不是 javascript 專家,但看看這個簡單的片段是否對你有幫助。
function DoSomething(steps) {
// Do stuff here steps--;
if (steps <
== 0) {
return;
} DoSomething(steps);
}
試試這個希望它會有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.