给定:用于解析网站上部分数据的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,并且在Web Worker中不提供DOM。许多开发人员都怀疑使用Web Workers。我只想问我是做对还是错。是否有更多我无法看到的表面解决方案?
答案 0 :(得分: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中实现它的唯一方法。如果你想编写一个看起来像循环的结构化版本而不是大量的getos,那么看一下异步控制流库或编译Javaascript扩展的编译器之一,将异步支持转换回常规JS回调。