【问题标题】:Javascript synchronous loop in browser浏览器中的 Javascript 同步循环
【发布时间】:2017-06-07 22:36:49
【问题描述】:

尝试使用 Greasemonkey 在浏览器中自动执行一项任务。

要求:加载一个网页,其中包含一个表格,显示 340 多个结果中的 15 个,并带有按钮控件以查看下一页的结果、返回、到最后等等。

  1. 收集前 15 个结果 --> 得到这个工作
  2. 单击“下一步”按钮 --> 开始工作
  3. 等待直到页面加载下一组结果 --> 不知道如何
  4. 重复直到下一个按钮被禁用 --> 得到这个工作

不能显示图片,因为它是一个公司应用程序。

到目前为止,如果我使用 setTimeouts 循环,超时会排队并在我认为的同时执行。相反,要求代码运行信息收集,单击下一步,等待,然后再次收集信息。

【问题讨论】:

  • -为什么要等待页面加载接下来的 15 个结果? !

标签: javascript asynchronous greasemonkey synchronous


【解决方案1】:

您可以尝试一个实用函数waitForKeyElement,一个greasemonkey 实用脚本。它本质上是在做你以前想做的事情。它设置了一个超时来持续检查元素是否被加载。执行它看起来像这样:

waitForKeyElements (
     "div.comments", 
     commentCallbackFunction
);

评论回调函数是收集结果的函数。

这也有助于理解为什么循环中的 setTimeout 不起作用。 setTimeout 不会阻止执行脚本以运行您的回调函数。它将该函数排队等待不早于您作为第二个参数传入的时间。因此,循环运行得非常快,而不是像您可能期望的那样在 3000ms, 6000ms, and 9000ms... 处获得函数调用,而是在 3000ms, 3001ms, 3002ms 处获得更接近函数调用的东西。

【讨论】:

    【解决方案2】:

    您可以通过同步执行器nsynjs顺序执行任意 JS 逻辑与 API 调用、递归和超时混合:

    function synchronousCode() {
        var i=0;
        while(true) {
          console.log("waiting 1 sec, iteration", i++);
          $('#myDiv').toggle();
          nsynWait(nsynjsCtx,1000);
        };
    }
    
    var ctx;
    function btnStopClicked() {
        ctx.stop();
        ctx=null;
    }
    
    function btnStartClicked() {
        ctx=nsynjs.run(synchronousCode,{},function(){
    			console.log("Synchronous Code done");
    		});
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
    <script src="https://rawgit.com/amaksr/nsynjs/master/nsynjs.js"></script>
    <script src="https://rawgit.com/amaksr/nsynjs/master/wrappers/nsynWait.js"></script>
    <body>
      <button id="buttonStart" onclick="btnStartClicked()">Start</button>
      <button id="buttonStop" onclick="btnStopClicked()">Stop</button>
      <div id="myDiv">Flashing div</div>
    </body>

    在此处查看更多示例:https://github.com/amaksr/nsynjs/tree/master/examples

    【讨论】:

      【解决方案3】:

      谢谢大家,发现这篇文章是最好的答案 Synchronous setTimeout + Loop

      这样页面加载,第一个值被读取,下一个按钮被点击,下一个结果出现并被读取,直到最后一页。

      再次感谢您的意见和想法

      【讨论】:

        【解决方案4】:

        你可以使用它

        for(const elment of arrayElements) {
                    await yourFunc(elment)
                    await yourOtherFunc('somePatameter')
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-05-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-06
          • 1970-01-01
          • 2017-11-10
          相关资源
          最近更新 更多