连续多次运行jQuery函数(对于Bookmarklet)

时间:2017-06-21 09:33:39

标签: javascript jquery

我在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次并行运行?

11 个答案:

答案 0 :(得分:6)

以这种方式尝试(使用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
  });

编辑:回来再次阅读你的问题,意识到你试图多次运行所有。我编辑过以反映这一点。

答案 1 :(得分:4)

只需重置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));
        }
    }
})();

答案 2 :(得分:0)

你应该看看Promises

在你的函数执行结束时解析你的Promise并再次调用你的函数。你应该对此很好。

答案 3 :(得分:0)

您有2个选项

1.使用用户脚本

为此,您需要一个用户脚本扩展管理器,例如Chrome的Tampermonkey,Firefox的Greasemonkey等。

但是既然你想要一个书签,那就留下吧。

2.稍微修改Bookmarklet如下

unfollow函数

中添加此代码

检查index是否达到0以及是否设置了标志。

FLAG很重要,否则会创建一个不定式的递归循环。

首先在FLAG函数之外将unfollow设置为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

答案 4 :(得分:0)

在您的特定情况下,您可以简单地构建一个包含每个按钮两次的数组:

// 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);

答案 5 :(得分:0)

据我了解你的要求,可以这样做:

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));
            }
    }
})();

答案 6 :(得分:0)

您可以使用递归来实现按顺序多次运行函数所需的效果。以下是如何做到这一点:

UserInterFaceOnly

答案 7 :(得分:0)

据我所知,Javascript在单个线程上运行,因此没有实际的并行处理。

如果你只是想让函数自己运行x次,那么使用递归:

   --allow-unauthenticated
       Ignore if packages can't be authenticated and don't prompt about it. This can be useful while working with
       local repositories, but is a huge security risk if data authenticity isn't ensured in another way by the user
       itself. The usage of the Trusted option for sources.list(5) entries should usually be preferred over this
       global override. Configuration Item: APT::Get::AllowUnauthenticated.

如果你想让事情在&#34; parallel&#34;使用Javascript然后你可能会考虑使用一些管理线程的外部代码并同时执行多个Javascript进程(虽然我不确定这是否可行,如果是的话,你是否能够让脚本同时访问相同的数据或彼此交谈。)

答案 8 :(得分:0)

我已将当前代码设为块并添加了包装器逻辑。检查是否有效。

(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));
            }
        }
     }
  }
})();

答案 9 :(得分:0)

声明一个标志/检查变量,例如。 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
}

M不是javascript的专家,但看看这个简单的代码片段是否对你有帮助。

答案 10 :(得分:0)

function DoSomething(steps) {

// Do stuff here steps--;
 if (steps <
== 0) {
 return;
 } DoSomething(steps);
 }  

尝试这个希望它会有用。