2015-01-17 4 views
0

У меня была проблема при попытке выполнить асинхронную функцию в JavaScript. В основном у меня есть pointArr для хранения координат вдоль маршрута. Затем я получил moveNext(), который берет в каждую координату вдоль маршрута и заносит на карту. Затем внутри moveNext() я получил еще один массив, который является busList. Если координаты по маршруту соответствуют координатам busList, то я минус totalBusStopLeft на единицу. Вот код, где я называю MoveNext():JavaScript Asynchronous Loop не возвращает результаты

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. Интересно, как я мог вернуть минус totalBusLoc из moveNext(). Есть идеи?

Я попытался использовать 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); 
} 
} 
+0

Во втором в moveNext вы вызываете обратный вызов, но не передаете обратный вызов, поэтому его сбой –

+0

@MukeshAgarwal Итак, есть ли у вас какие-либо идеи, как это исправить? – hyperfkcb

+0

В 'moveNext()' вы только обновляете локальную переменную (параметр) 'totalBusLoc', переменную, которая исчезает, когда функция заканчивается. Вам нужно будет удалить этот параметр и вместо этого определить его как переменную в области содержимого, чтобы сохранить ее значение между вызовами 'moveNext()'. Или прочитайте и проанализируйте '.innerHTML' из элемента '' busStopLeft '' и increment *, что *. (Кстати, вызывая 'parseFloat()' в этой строке: 'parseFloat (totalBusLoc -);' ничего не делает, потому что вы не используете возвращаемое значение.) – nnnnnn

ответ

1

Вводя параметр callback для moveNext() функции не помогает если вы фактически не передаете функцию при вызове moveNext(). Код, который вы указали, все еще передает только исходные пять аргументов, поэтому, когда вы пытаетесь использовать callback(totalBusLoc), вы обнаружите, что callback - undefined.

Таким образом, вы могли бы изменить вызов 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 в коде, который я показал, ссылаются на переменную той же переменной.

(Примечание: Я также немного упростил код. Если у вас были переменные, которые использовались только один раз после того, как мне присвоено значение, я избавился от этих переменных. Но то, что я показал, все равно должен сделать то же самое.)

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'); 
    } 
    }); 
+0

С async.eachSeries мне нужно было импортировать async.js. Как я уже упоминал в вопросе выше, файл сбой с библиотекой додзё – hyperfkcb

+0

@Denise ahh хорошо пропустил, что я думаю. –

Смежные вопросы