[英]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.