JavaScript异步循环不返回结果

时间:2015-01-17 03:23:56

标签: javascript loops asynchronous dojo

尝试在JavaScript中执行异步功能时遇到了一些问题。基本上我有一个pointArr来存储沿路线的坐标。然后我得到一个moveNext(),它接收沿着路线的每个坐标并绘制到地图上。然后在moveNext()内部,我得到另一个数组,它是busList。如果沿着路线的坐标与busList的坐标匹配,那么我将totalBusStopLeft减去一。这是我调用moveNext()的代码:

 getAllBusLoc(function(busList) {
            //At first I set the totalBusLeft by the length of busList which is 13 in this case
            var totalBusLoc = busList.length;
            document.getElementById("busStopLeft").innerHTML = totalBusLoc;
                 timeout = 1500;
            pointArr.forEach(function(coord,index){
                setTimeout(function(){
                    moveNext(coord.x, coord.y, index, busList, totalBusLoc);
                }, timeout * index);
            });
        });

function moveNext(coordx, coordy, k, busList, totalBusLoc ){
//pointToCompare is the coordinates in the route but not the coordinates of busList
var pointToCompare = coordx + "," + coordy;

//If the coordinates in route matches the coordinate in busList, I minus busLeft by one
if(busList.indexOf(pointToCompare) > -1){
     parseFloat(totalBusLoc--);
             document.getElementById("busStopLeft").innerHTML = totalBusLoc ;

}

//Code to Add marker

}

但是,使用此代码,我的Html组件busStopLeft继续显示13,这是原始的totalBusLoc。我想知道如何从moveNext()返回minused totalBusLoc。有任何想法吗?

我曾尝试使用async.eachSeries但是当我导入async.js时,它给了我另一条错误消息,它与dojo崩溃。 提前谢谢。

以下是我尝试使用回调的部分:

totalBusLoc = busList.length;
        document.getElementById("busStopLeft").innerHTML = totalBusLoc;
        timeout = 1500;
        pointArr.forEach(function(coord,index){
            setTimeout(function(busLeft){
                moveNext(coord.x, coord.y, index, busList, totalBusLoc);
            }, timeout * index);
        });
    });


function moveNext(coordx, coordy, k, busList, totalBusLoc, callback){
var pointToCompare = coordx + "," + coordy;
 if(busList.indexOf(pointToCompare) > -1){
 parseFloat(totalBusLoc--);
 document.getElementById("busStopLeft").innerHTML = totalBusLoc;
 callback(totalBusLoc);
}
}

2 个答案:

答案 0 :(得分:1)

如果您在致电callback时未实际传递函数,则为moveNext()函数引入moveNext()参数并不会有所帮助。您显示的代码仍然只传递原来的五个参数,因此当您尝试使用callback(totalBusLoc)时,您会发现callbackundefined

因此,您可以将调用更改为moveNext()以传递回调函数:

moveNext(coord.x, coord.y, index, busList, totalBusLoc, function(newTotalBusLoc) {
  totalBusLoc = newTotalBusLoc;
});

这应该有效,因为我引入的函数在范围内有原始的totalBusLoc变量。

但它似乎有点混乱,像那样来回传递价值。鉴于您在评论中确认moveNext()未在其他任何地方使用且且不包含太多代码,我可能会删除该功能并将其身体直接移至匿名函数中您传递给setTimeout()

getAllBusLoc(function(busList) {           
    var totalBusLoc = busList.length;
    document.getElementById("busStopLeft").innerHTML = totalBusLoc;
    pointArr.forEach(function(coord,index){
        setTimeout(function(){
            if (busList.indexOf(coord.x + "," + coord.y) > -1)
                document.getElementById("busStopLeft").innerHTML = --totalBusLoc;
        }, 1500* index);
    });
});

传递给setTimeout()的内部匿名函数可以访问在其包含函数中声明的变量,因此它可以直接访问外部totalBusLoc变量。也就是说,在我显示的代码中引用totalBusLoc的所有三个位置都引用了相同的变量。

(注意:我还简化了你的代码。如果你有一些变量,只有在分配了一个值后才使用一次,我就摆脱了那些变量。但是我所展示的仍然应该做同样的事情。 )

答案 1 :(得分:0)

您可以使用async尝试类似的内容:

  index = 0;
  async.eachSeries(pointArr, function(coord, moveNext){
      moveNext(coord.x, coord.y, index, busList, totalBusLoc);
      index = index + 1;
    }, function(err){
      if( err ) {
        console.log('Failed');
    }
  });