2013-04-30 4 views
3

다음 코드 조각에는 버그가 있지만 흥미로운 질문이 열렸습니다. 그것의 약속을 반환 각도의 $ HTTP 서비스를 사용하여. 일단 해결되면 콜백 함수는 s1 변수에 액세스 할 수 없습니다.콜백 함수가 클로저 변수에 액세스합니까?

var ids = []; 
    ids = ['81074']; 

    // show what's in 
    for (var s=0;s<ids.length;s++) { 
     var s1 = s; 
     $http.get('http://mydomain.com/api/catalog/product/' + ids[s]). 
       success(function(data) { 
     // console.log(s1); <--- reference error 
      $scope.products[s].setProductData(data); 

     }).error(function(err){ 
       console.log('--------- error',err); 
      }); 
    }; 

(S1)는 ReferenceError가 있습니다 : (S1)는 항상 1

그리고 흥미롭게도, 그것은 루프 변수들에 대한 액세스 권한을 가지고 디버거, 정의되어 있지 않습니다 - 약속이 후 해결되었다 때문에, 예상대로 그 증가 (따라서 버그 BTW)

누군가가 왜 설명 할 수 있습니까?

감사

리 오르

+1

's1'을 사용하지 못하고 어디에서 오류가 발생합니까? – Barmar

+0

코드가 정의 된 후 s1을 참조하지 않습니다. 참조 오류가 발생하는 이유는 무엇입니까? – KevSheedy

+0

콜백 내부에서 디버거에서 s1을 확인했습니다. 코드가 편집되었습니다. 비고에 대한 감사합니다 – Lior

답변

9

이것은 for 루프에서 비동기 콜백과 고전적인 문제입니다. ss1은 한 번만 선언됩니다. 루프 내에서 var s1;을 선언하더라도 JavaScript에는 블록 범위가 없으므로 관련이 없습니다.

이 모든 반복이 같은 변수를 공유 의미 ss1, 그래서 콜백이 완료되면, $scope.products[s]ids.length + 1 제품을 찾고 있습니다. 대신

가 수행 s 여전히 해결 콜백 함수 내부 s 수단 launchRequest 내부 새로운 기능 레벨 범위를 도입

var ids = []; 
ids = ['81074']; 

function launchRequest(s) { 
    $http.get('http://example.com/api/catalog/product/' + ids[s]).success(function (data) { 
     $scope.products[s].setProductData(data); 
    }).error(function (err) { 
     console.log('--------- error', err); 
    }); 
} 

// show what's in 
for (var s = 0; s < ids.length; s++) { 
    launchRequest(s); 
} 

....

+0

@Matt에게 감사드립니다. s에 대해 이해하고 귀하의 제안에 감사드립니다! (찍은). 여전히 원래 코드에서 콜백 내부에서 s1이 보이지 않는 이유는 무엇입니까? 거기에 s1이 보이게하려면 어떻게해야합니까? – Lior

+0

괜찮 았어. 미안 해요 - 내 벌레. s1은 명시 적으로 작성하는 한 볼 수 있습니다. – Lior

관련 문제