我有一个Array.each函数,每次循环运行25次时我需要暂停5秒钟。
Array.each(response.data, function(thing, index){
sendEmail(thing.id,sku,thing.email);
});
我尝试了各种方法,但它总是只是调用sendEMail函数而没有延迟。有谁知道怎么做?
循环可以运行15到500次,具体取决于发送给它的数据。
感谢。
Mootools 1.4.5
答案 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/ 会做的。