【问题标题】:Do I need Web Workers for looping AJAX-requests?我需要 Web Worker 来循环 AJAX 请求吗?
【发布时间】:2014-02-05 19:38:37
【问题描述】:

Given:一个用于解析网站上部分数据的 php 脚本。它解析大约 10k 产品,因此相当慢。

我需要为它制作一个带有 html/css/js 的网络前端。我做了一个循环,它发出 ajax 请求并显示进度信息。它使用同步 ajax,因为它需要等到另一个请求完成才能执行另一个。

 do {
    var parseProductsActive = true;
    var counter = 0;
    myAjax('parseProducts.php?start='+counter, false, function(resp) {
        if (resp[0]=='s') {
            counter += Number(resp.substring(1));
            parseProductsActive = false;
        }
        else {
            counter += Number(resp);
        }   
        self.postMessage(counter);  
    });
 } while (parseProductsActive==true);

我在 Web Worker 中这样做是因为我担心它会因为这个无限循环而挂起界面,并且(a)ajax 本身的同步性无助于解决问题。

但是当我尝试在 Web Worker 中使用 ajax 时,我发现虽然可行,但它很难,因为 jQuery 根本不能在 Web Worker 中工作。它甚至将 DOM 用于非 DOM 操作,并且 DOM 在 Web Worker 中不可用。许多开发人员根本怀疑使用 Web Workers。我只是想问我这样做是对还是错。还有其他我看不到的表面解决方案吗?

【问题讨论】:

  • 您能否在不使用 Web Worker 的情况下一次将您的记录 AJAX,例如 100 条,并动态更新显示?
  • 跟我说的不一样吗?它怎么不会挂在页面上?如果我们用循环编写它。
  • 不,您在异步(真正的 AJAX)中抓取 100 条记录(AT ONCE),显示它们,然后在第一个请求完成后再获取 100 条记录。
  • >然后在第一个请求完成后去获取另一个 100。 “那么”是什么意思?我在哪里写?你建议递归回调吗?

标签: javascript ajax web-worker


【解决方案1】:

您猜对了:递归回调是按顺序执行一堆异步请求的方式。它可能看起来有点像这样:

var parseProductsActive = true;
var counter = 0;

//define the loop
function doNextAjax(allDone){
   //Instead of just returning, an async function needs to 
   //call the code that comes after it explicitly. Receiving a callback
   //lets use not hardcode what comes after the loop.

  if(!parseProductsActive){
    allDone();
  }else{
    //use async Ajax:
    myAjax('parseProducts.php?start='+counter, true, function(resp) {
        if (resp[0]=='s') {
            counter += Number(resp.substring(1));
            parseProductsActive = false;
        }
        else {
            counter += Number(resp);
        }   
        self.postMessage(counter);

        doNextAjax(); // <---
    });
}

//Start the loop
doNextAjax(function(){
  console.log("the code that runs after the loop goes here")
});

//BTW, you might be able to get rid of the "parseProductsActive" flag with a small
// refactoring but I'm keeping the code as similar as possible for now.
//It would be kind of equivalent to writing your original loop using a break statement.

是的,它丑陋而冗长,但它是在原始 Javascript 中实现它的唯一方法。如果您想编写一个看起来像循环而不是带有大量 goto 的更结构化的版本,请查看其中一个异步控制流库或将具有异步支持的 Javaascript 扩展编译回常规 JS 的编译器之一带有回调。

【讨论】:

  • 仍然,Web Workers 不好吗?考虑到旧版浏览器不支持普通用户,不适合普通用户,但对于将使用解析器的单个用户。我的解决方案可以实现吗?
  • 你可以在这里使用 webworkers,但它没有那么有用。 webworkers 的目的是让你在一个单独的线程中进行大量密集的 JS 处理,但在这种情况下,你只做很少的处理,需要等待服务器响应。最后,如果您关心的是能够使用循环而不是递归来编写代码,那么使用 CPS 编译器是一种更直接且兼容的解决方案。
  • 另一个问题。如果我们有一堆 ajax 请求不是按顺序而是在物理上并行运行怎么办?我可以在没有 Web Worker 的情况下运行并行 ajax 请求,以便从并行化性能中受益吗?
  • 如果您想一次使用多个线程/核心,您将需要网络工作者。但是,如果您正在做与现在类似的事情,几乎没有处理和大量等待,那么您可以通过回调合作完成所有事情:stackoverflow.com/a/15204642/90511
  • 我试过这个,但尽管它们以不同的顺序完成,但它们的工作时间就像同步运行一样。与网络工作者或 iframe 一起运行它们给了我巨大的性能优势。有点奇怪。我在哪里可以详细了解 ajax 的实现?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-06
  • 2019-03-24
  • 1970-01-01
  • 2013-11-09
  • 1970-01-01
  • 2021-03-15
  • 2011-11-06
相关资源
最近更新 更多