forEach里面的异步函数用js循环 [英] Async functions inside forEach loops with js

查看:142
本文介绍了forEach里面的异步函数用js循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

javascript:执行一堆带有一个回调的异步方法

我几天来一直在努力解决这个问题,但我无法找到一种优雅的方式来处理它。这是问题。

I've been struggling with this issue for days now, but I just can't figure out an elegant way to handle it. Here's the problem.

我正在运行forEach循环,我需要知道什么时候一切都已完成。由于forEach循环是阻塞的,因此只需在forEach循环之后删除 console.log 就足够了,这将在forEach循环完成时运行。但是,如果forEach循环内部有任何不同步的函数,整个系统会很快崩溃,除了非常奇怪的hacky计数器和if语句之外,我无法知道循环的内容何时完成。我的问题是在javascript中是否有一种优雅的方式来处理这种情况。

I'm running a forEach loop, and I need to know when everything has been completed. Since forEach loops are blocking, it should be easy enough to just drop a console.log after the forEach loop, which will run when the forEach loop is complete. However, if there is any function inside of the forEach loop that's not sync, this entire system breaks down very quickly, and I have no way of knowing when the contents of the loop are complete other than very strange hacky counters and if statements. My question is whether there is an elegant way to handle this situation in javascript.

以下是几个例子:

在这种情况下,forEach循环可以很好地工作,因为循环中的所有内容都是同步的。

In this case, the forEach loop works perfectly nicely, since everything in the loop is sync.

[1,2,3].forEach(function(num){
  console.log("we're on " + num);
});
console.log('done counting!')

//=> we're on 1
//=> we're on 2
//=> we're on 3
//=> done counting!

这是我们开始遇到问题的地方,作为一个基本的例子:

This is where we start running into problems though, as a basic example:

[1,2,3].forEach(function(num){
  setTimeout(function(){ console.log(num) }, 200);
});
console.log('done counting!');

//=> done counting!
//=> we're on 1
//=> we're on 2
//=> we're on 3

虽然这确实有意义,但我现在有一个不幸的问题在我的手上,当我们完成计数时,我需要一个回调,并且我没有顺利的方式来获得除此之外的其他东西:

Although it does make sense that this is happening, I now have the unfortunate issue on my hands that I need a callback for when we are done counting, and there's no smooth way for me to have one other than something gross like this:

var counter = 0;
var numbers = [1,2,3]

var log_number = function(num){
  console.log("we're on " + num);
  counter++;
  if (counter == numbers.length) {
    console.log("done counting!")
  }
}

numbers.forEach(function(num){
  setTimeout(log_number(num), 200);
});

//=> we're on 1
//=> we're on 2
//=> we're on 3
//=> done counting!

天哪,这是一个非常大的开销。有没有更顺畅的方法来实现这一目标?我已经检查了promises,deferred和sequence,但我还没有真正能够以一种更简洁的方式实现其中任何一个:(

Goodness, that's an awful lot of overhead. Is there any smoother way to make this happen? I've checked out promises, deferred's, and sequences, but I haven't really been able to implement any one of them in a way that makes this more concise : (

要明确的是,它不是setTimeout特别是我的问题,它通常在同步函数内运行异步函数 - 这只是最简单的例子。

To be clear, it's not setTimeout specifically that is my issue, it generally having async functions running inside a sync function - that was just the simplest example.

推荐答案

Array.prototype.forEachDone = function(fn, scope, lastfn) {
    for(var i = 0, c = 0, len = this.length; i < len; i++) {
        fn.call(scope, this[i], i, this, function() {
            ++c === len && lastfn();
        });
    }
};

[1,2,3].forEachDone(function(num, i, arr, done){
  setTimeout(function(){ console.log(num); done() }, 200);
}, this, function() {
    console.log('done counting!');
});

这将满足您的需求.forEachDone将采取确切的山姆e参数为forEach,最后有一个参数,它是在应用于数组的每个元素的函数完成时调用的回调。将应用于数组中每个元素的函数也采用与forEach完全相同的参数,但也使用另一个函数,该函数应在函数完成时调用。

this will do what you're looking for. forEachDone will take the exact same parameters as forEach, with an additional one at the end that is a callback to be called when the functions applied to each element of the array are done. the function that'll be applied to each element in the array also takes the exact same parameters as in forEach but also with an additional one that is a function that should be called when the function finishes.

PS:就个人而言,我永远不会触及本机对象的原型,但如果你正在寻找漂亮,那就是它。

PS: personally, i'd never touch a native object's prototype, but if you're looking for pretty, this is it.

这篇关于forEach里面的异步函数用js循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆