2013-02-15 113 views
1

我有一個Array.each函數,每次循環運行25次時需要暫停5秒。Mootools每5秒暫停Array.each循環

Array.each(response.data, function(thing, index){ 
    sendEmail(thing.id,sku,thing.email); 
}); 

我已經試過各種方法,但它始終只是調用sendEMail功能沒有延遲。有誰知道如何做到這一點?

根據發送給它的數據,循環可以運行15到500次。

謝謝。

MooTools的1.4.5

+2

不要嘗試暫停循環。相反,使用計時器並從其回調中循環塊數據。 – bfavaretto 2013-02-15 04:37:07

回答

1

您將無法通過循環停止的循環迭代部分的方式,除非Array.each可以讓你從內回調傳遞的早期退出了,並允許你從恢復任意索引。你仍然需要將邏輯包裹在它周圍來處理暫停。

另一種方法是推出自己的。

var eachWithPause = function(iterable, iterations, timeout, fn, ctx) { 
    // Sets up a callback to be passed back to the caller, allowing them 
    // to cancel the `setTimeout` call created within `loop`. 
    var timeoutID = 0; 
    var cancel = function() { 
    clearTimeout(timeoutID); 
    }; 

    // `loop` will run the desired number of iterations, or iterate through 
    // the remainder of the `iterable`, whichever comes first. If there are 
    // still elements left after it is done, it will `setTimeout` for the 
    // desired amount of time. 
    var index = 0, l = iterable.length; 
    var loop = function() { 
    for (var i = 0; i < iterations && index < l; ++i, ++index) { 
     fn.call(ctx, iterable[ index ], index, iterable); 
    } 

    if (index < l) { 
     timeoutID = setTimeout(loop, timeout); 
    } else { 
     timeoutID = 0; 
    } 
    }; 

    loop(); 
    return cancel; 
}; 

唯一有趣的我在這裏做返回一個cancel功能,將提供呼叫者的方式來調用clearTimeout在一個不斷變化的setTimeout,它並不能訪問。

你將不得不類似於

var cancel = eachWithPause(response.data, 5, 5000, function(thing, index) { 
    sendEmail(thing.id, sku, thing.email); 
}); 

的東西,如果你需要取消該操作,然後你可以簡單cancel()它。

1

我想去更通用的塊組方法。

Array.implement({ 
    chunkEach: function(offset, count, delay, fn, bind){ 
     // get a chunk 
     var newOffset = offset + count, 
      chunk = this.slice(offset, newOffset), 
      ii = 0, 
      len = chunk.length; 

     if (!len) 
      return this; 

     // loop the chunk supporting natural index. 
     for (; ii< len; ++ii) 
      fn.call(bind, chunk[ii], offset + ii); 

     // move pointer and self call 
     if (newOffset < this.length) 
      this.chunkEach.delay(delay, this, [newOffset, count, delay, fn, bind]); 

     // pointless chaining return as its async. 
     return this; 
    } 
}); 

使用,在以2秒鐘的暫停的15塊的電子郵件地址的例如環陣列,保持的功能範圍的假想物體與選項屬性:

list.chunkEach(0, 15, 2000, function(el, index){ 
    console.log(this.options); 
    new Element('div[html='+index + '. ' + el +']').inject(o); 
}, this); 

看到http://jsfiddle.net/dimitar/aYwab/

其粗糙 - 缺乏對參數和東西的檢查,但它會做你想做的。

可能存在關於在此解決延遲的責任的問題。你正在發送電子郵件,大概是通過Ajax。不明確的延遲是不可縮放的。

你應該看看使得sendEmail功能可鏈接 - 簡單數組和索引傳遞到它,如果指數小於數組長度 - 1,再次從onSuccess下一個指數叫sendEmail。這還允許您在上次發送失敗時中斷或重試。

另外,你可以使用Promise。

0

我會分裂成兩個不同的子問題你ploblem,你想辦法到的組的陣列的X項:

Array.implement('paginate', function(count){ 
    var result = [], pageIndex = -1 

    for(var i=0, max = this.length; i<max; i++){ 
     if (i%count==0){ 
      pageIndex++ 
      result.push([]) 
     } 

     result[pageIndex].push(this[i])    
    } 
    return result; 
}); 

,那麼你要處理各自爲陣的「頁」和前等待Y秒對其他數據做任何事情。

function process(data, index, delay){ 
    workondata(data[index]); 
    if(data.length-index >1) setTimeout(
     function(){ 
      process(data, index +1, delay) 
     }, 
     delay 
    ); 
} 

因此,我相信是這樣的:http://jsfiddle.net/kentaromiura/SmyU8/ 會做這項工作。