2012-12-04 2 views
0

각도 응용 프로그램에서 작업 중이며 문제가 있습니다. 나는 JS에 매우 익숙하며 비동기 프로그래밍에 새로운 것이므로 뭔가 확실한 것을 놓치고 있다고 생각합니다.For 루프 비동기

문제의 요지는 배열을 빌드하는 for 루프가 있다는 것입니다. 그런 다음 for 루프가 완료되면 해당 배열에 가입해야합니다. 일반적으로 이것은 brainer가 아니지만 for 각도에서 분명히 비동기 적으로 실행됩니다. 다음에 루프가 종료되도록 배열을 강제로 생성해야합니다. . 내가 볼 수있는 출력을 검사 할 때 놀랍게도

if(!data.results[i].is_deleted) { 
    var objectsOnCurrentPermission = new Array(); 
    if(data.results[i].objects) { 
    for(var j = 0; j < data.results[i].objects.length; j++) { 
     var currentObjectId = data.results[i].objects[j].object_id; 
     var currentObjectName; 
     var objectData = Object.get({id: currentObjectId}, function(objectData) { 
     objectsOnCurrentPermission.push(objectData.name); 
     console.log('in loop in get fn'); 
     console.log(objectsOnCurrentPermission); 
     }); 
    } 
    console.log('after loop'); 
    console.log(objectsOnCurrentPermission); 
    var listOfObjectsOnCurrentPermission = objectsOnCurrentPermission.join(', '); 
    console.log('str after assignment'); 
    console.log(listOfObjectsOnCurrentPermission); 
    data.results[i]['objects_list'] = listOfObjectsOnCurrentPermission; 
} 

after loop permissions.js:246 
>Array[1] 
permissions.js:247 
str after assignment permissions.js:249 

permissions.js:250 
in loop in fn permissions.js:242 
>Array[1] 

당신은 루프 출력 후 처음 실행하는 것을 볼 수있다 (I 가독성을위한 '<'에 추가 된). 내가 말할 수있는 것부터, Array [1]을 처음 출력 할 때 배열은 실제로 채워지지 않습니다. 크롬은 사실 후에 그것을 채 웁니다. "str after assignment"라고 쓰여진 줄 다음의 빈 줄은 분명히 작동하지 않는 조인을 출력하려고하는 곳입니다. 마지막으로 루프의 코드가 실행됩니다. 앞서 언급했듯이 for 루프가 배열 채우기를 마친 후에 배열 조인이 수행되는지 확인해야합니다.

+0

Angular에서 $ q를 보았습니까? (적어도 나를 위해) 이것은 우아하게 내 비동기 문제를 해결했습니다. –

답변

0

:

다음은 모든 .get() 방법을 완료 한 경우를 추적 한 다음 최종 코드를 실행할 것입니다 방법에 대한 기본적인 생각 필요합니다. 특히 async.parallel을 사용하면 중간 배열을 빌드하고 계속 진행하기 전에 완료되었는지 확인할 수있었습니다. https://github.com/caolan/async

3

console.log() 출력을 기준으로 Object.get() 함수는 비동기 적이어야합니다. 즉, 호출은 호출을 시작하고 나중에 약간의 시간이 끝난다는 것을 의미합니다. 아마, 그것이 끝나면, 당신이 그것을 통과 콜백 함수를 호출합니다.

따라서 최종 결과 처리를 완료하려면 Object.get() 호출이 완료되었을 때 - 완료 콜백이 모두 Object.get() 인 경우 최종 코드를 트리거해야합니다. 남아있는 수를 추적하는 간단한 카운터는이를 수행하는 간단한 방법 중 하나입니다. 내 동기/비동기 코드를 관리 할 수 ​​caolan의 비동기 라이브러리를 사용하여 결국

if(!data.results[i].is_deleted) { 
    var objectsOnCurrentPermission = []; 
    if(data.results[i].objects) { 

    // initialize counter so we know when all async functions are done 
    var numRemaining = data.results[i].objects.length; 

    for(var j = 0; j < data.results[i].objects.length; j++) { 
     var currentObjectId = data.results[i].objects[j].object_id; 
     var currentObjectName; 
     var objectData = Object.get({id: currentObjectId}, function(objectData) { 
     objectsOnCurrentPermission.push(objectData.name); 
     console.log('get complete fn called'); 
     console.log(objectsOnCurrentPermission); 
     --numRemaining; 
     if (numRemaining === 0) { 
      console.log('all get() functions done'); 
      console.log(objectsOnCurrentPermission); 
      var listOfObjectsOnCurrentPermission = objectsOnCurrentPermission.join(', '); 
      console.log('str after assignment'); 
      console.log(listOfObjectsOnCurrentPermission); 
      data.results[i]['objects_list'] = listOfObjectsOnCurrentPermission; 
     } 
     }); 
    } 
}