簡體   English   中英

另一個異步循環中的Javascript異步循環

[英]Javascript async loop inside another async loop

我在jQuery中有一些代碼可以使用each()遍歷div中的子級。 里面的每個文本都被分解成單詞。 每個單詞都使用“ for”循環進行處理。 此功能可能需要很長時間並且可能會凍結瀏覽器,因此...

有沒有一種方法可以在另一個異步循環中創建異步循環,但是一個正在等待其他循環完成?

誰能告訴我正確的方向?

我想到了這樣的東西:

var queue = [];
var nlevel = 0;

function work() {
    nlevel = queue.length-1;

    var arr = queue[nlevel][0];
    var process = queue[nlevel][1];
    var cnt = queue[nlevel][2];
    var item = arr[cnt];

    process.apply(item);

    cnt++;
    queue[nlevel][2] = cnt;

    if (cnt < arr.length) {
        setTimeout(work, 1);
    } else {
        if (queue.length>1) {
            queue.pop();
            setTimeout(work, 1);
        }
    }
}

function each(arr, process) {
    queue.push([arr, process, 0]);

    setTimeout(work, 1);
}


each(['one', 'two', 'three'], function() {
    alert(this);

    each([1, 2, 3, 4], function() {
        alert(this);
    });
});

但它有一些重大錯誤,我無法修復。

您可以使用Web Workers在后台線程中運行多個腳本。 但是並非所有瀏覽器都支持它們。 請參閱來自Mozilla的這篇文章或直接向Google提問: https : //developer.mozilla.org/En/Using_web_workers

您可以定期使用SetTimeout(0,...)對瀏覽器“屈服”控制以防止凍結瀏覽器(但它的執行速度不會更快,實際上可能會稍慢一些)。

請參閱此答案以獲取有關該技術的示例,在沒有看到您的代碼的情況下我無法更加具體。

一種方法是創建要處理的工作項目隊列:

var queue = [];

將要處理的項目放在此隊列中,而不是立即處理:

queue.push(item);

然后啟動計時器循環以處理項目:

var delayBetweenItems = 10;
var processItemFromQueue = function() {
    if (queue.length) {
        item = queue.shift();
        doStuff(item);
        setTimeout(delayBetweenItems, processItemFromQueue);
    }
};
setTimeout(processItemFromQueue, delayBetweenItems);

假設您當前的代碼與此類似:

function processWord(word, i, j) {
   // do something with the current word, where
   // (if it's needed) i is the index into the elements
   // and j is the index into the current element's words
}

$("#divId").children().each(function(i) {
    var words = $(this).text().split(" "),
        j;
    for(j = 0; j < words.length; j++) {
       processWord(words[j], i, j);
    }
});

您可以重寫該代碼以使用setTimeout()進行外部(i)和內部(j)循環:

// assumes the same processWord() function as above

(function (){
    var $items = $("#divId").children(),
        words,
        i, j,
        iMax, jMax;

    function doIteration() {
       if (j === jMax) {
          if (++i === iMax)
             return;

          // outer loop processing
          words = $($items[i]).text().split(" ");
          jMax = words.length;
          j = 0;
       }
       if (j < jMax) {
          // inner loop processing
          processWord(words[j], i, j);
          j++;
       }

       setTimeout(doIteration, 1);
    }

    iMax = $items.length;
    i = j = jMax = -1;
    doIteration();
})();

工作演示: http : //jsfiddle.net/sp8Wr/

doIteration()函數通過適當地處理一些計數器並通過setTimeout()調用自身以進行下一次迭代來模擬嵌套循環。 立即執行的匿名函數將整個內容包裝起來對於該過程而言不是必不可少的,它只是限制了變量的范圍。

是的,這可能做得更好,但這只是我即時想到的-很明顯,您將對其進行修改以適合您自己的處理。

(如果你不關心什么順序的話得到的,只要處理為processWord()函數獲取的正確的價值觀ij與每個單詞相關聯。這可以很容易地做出更為整潔,但我沒有時間來進行順序處理的更整潔的版本。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM