2014-05-09 2 views
3

Q 구현 $ q에 대한 AngularJS의 설명서에 대한 도움말을 따르고 있습니다. 나는 나의 이해는 scope.apply 여기에 $ 콜백에게 각도의 컨텍스트를주고 $ 범위에서 확인 변수를하게 접근 할 수 있다는 것이다 https://docs.angularjs.org/api/ng/service/$q

// for the purpose of this example let's assume that variables `$q`, `scope` and `okToGreet` 
    // are available in the current lexical scope (they could have been injected or passed in). 

    function asyncGreet(name) { 
    var deferred = $q.defer(); 

    setTimeout(function() { 
     // since this fn executes async in a future turn of the event loop, we need to wrap 
     // our code into an $apply call so that the model changes are properly observed. 
     scope.$apply(function() { 
     deferred.notify('About to greet ' + name + '.'); 

     if (okToGreet(name)) { 
      deferred.resolve('Hello, ' + name + '!'); 
     } else { 
      deferred.reject('Greeting ' + name + ' is not allowed.'); 
     } 
     }); 
    }, 1000); 

    return deferred.promise; 
    } 

    var promise = asyncGreet('Robin Hood'); 
    promise.then(function(greeting) { 
    alert('Success: ' + greeting); 
    }, function(reason) { 
    alert('Failed: ' + reason); 
    }, function(update) { 
    alert('Got notification: ' + update); 
    }); 

에서 다음 코드를 시도했다.

그러나 아래에 $의 Q와 크리스 Kowal의의 Q 비교에

는, 테스트 코드가 간다 :

it('should simulate promise', inject(function($q, $rootScope) { 
    var deferred = $q.defer(); 
    var promise = deferred.promise; 
    var resolvedValue; 

    promise.then(function(value) { resolvedValue = value; }); 
    expect(resolvedValue).toBeUndefined(); 

    // Simulate resolving of promise 
    deferred.resolve(123); 

    // Note that the 'then' function does not get called synchronously. 
    // This is because we want the promise API to always be async, whether or not 
    // it got called synchronously or asynchronously. 
    expect(resolvedValue).toBeUndefined(); // <= so the deferred is not resolved without the 'apply'? 

    // Propagate promise resolution to 'then' functions using $apply(). 
    $rootScope.$apply(); 
    expect(resolvedValue).toEqual(123); 
})); 

은 $ rootScope 말한다 $ 적용() 약속 해상도 '다음'을 전파하는 것입니다.. 나는 혼란 스럽다 ... 적용을 사용하지 않고, 연기 된 해석은 실제로 해결되지 않을 것인가?

답변

7

이 문서는 끔찍합니다.

따라서 $q의 내용은 약속이 해결되었을 때 (또한 아마도 거부 또는 알림시) $rootScope.evalAsync 내의 처리기를 호출하여 호출 한 후 다이제스트를 트리거하고 나머지는 응용 프로그램은 우리가 좋아하는 방식으로 변경 사항을 업데이트하거나 응답 할 수 있습니다.

알다시피, it works just fine without the explicit $apply in an example app. 그러나 그들이 $apply을 명시 적으로 수행하는 이유는 $evalAsync 인 자동 화일이 테스트에서 동 기적으로 실행될 때 을 사용할 기회를 얻지 못하기 때문입니다. 응용 프로그램이 Just Work로 작동해야하기 때문에가 아닙니다. ™. 우리는 비동기 HTTP 요청/응답 또는 (예를 들어) 타임 아웃을 시뮬레이션 할 때 $http$timeout처럼 angular-mock.js에서 테스트를 증강하는 몇 가지 다른 주목할만한 서비스와

, 우리는 명시 적으로 플러시 할 수 있습니다. eval ed가되기를 기다리는 물건에 해당하는 것은 다이제스트를 트리거하는 것으로서, 적절한 컨텍스트에서 약속 핸들러를 호출합니다. 이것은 $apply 또는 $digest으로 이루어지며, 따라서 예제가이라는 동기 테스트로 작성되었으므로 ... 으로 표시됩니다.

문서는 테스트를 수행하기 위해 수행해야하는 작업과 작업을 완료하기 위해 애플리케이션 자체에서 집중해야하는 작업의 차이점을 설명해야합니다. 문서는 테스트 사실을 예제로 삼는 습관이 있으며 사람들을 혼란스럽게합니다.

희망이 있습니다.

+0

감사합니다. 귀하의 설명에 많은 도움이됩니다. :) – lkahtz

관련 문제