Mootools每5秒暂停一次Array.each循环

时间:2013-02-15 04:23:58

标签: javascript arrays mootools

我有一个Array.each函数,每次循环运行25次时我需要暂停5秒钟。

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

我尝试了各种方法,但它总是只是调用sendEMail函数而没有延迟。有谁知道怎么做?

循环可以运行15到500次,具体取决于发送给它的数据。

感谢。

Mootools 1.4.5

3 个答案:

答案 0 :(得分: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}}即可。

答案 1 :(得分: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;
    }
});

使用,例如15个块的电子邮件地址循环数组,暂停2秒,将函数范围保持为具有options属性的虚构对象:

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函数可链接 - 只需将数组和索引传递给它,如果index小于数组长度 - 1,再从{{1}调用sendEmail使用下一个索引。如果上次发送失败,这也允许您中断或重试。

另外,你可以使用Promises。

答案 2 :(得分:0)

我会将你的问题分成两个不同的子问题,你想要一种方法来按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/ 会做的。