Angular $ q 약속이 해결되었는지 확인하는 방법


84

나는 일반적으로 then()약속을 사용할 때 호출 및 체인 동작과 함께 연속 코드를 첨부한다는 것을 이해합니다 .

그러나 $timeout()원래 promise가 아직 완료되지 않은 경우에만 UI 작업을 수행 할 수 있도록 promise 래핑 된 비동기 호출을 시작한 다음 3 초를 별도로 시작하고 싶습니다. (저는 연결이 느린 경우, 3G의 모바일 장치 등에서 만 발생할 것으로 예상합니다.)

약속이 주어지면 차단하거나 기다리지 않고 완료 여부를 확인할 수 있습니까?


2
나는 각이에 문제를 열어 도움이 응답 가지고 github.com/angular/angular.js/issues/8307#issuecomment-49903373
derekdreery

답변:


46

나는 이것이 Angular의 최신 버전에 추가되었다고 생각하지만 이제 약속에 $$ state 객체가있는 것 같습니다.

 var deferred = $q.defer();
 console.log(deferred.promise.$$state.status); // 0
 deferred.resolve();
 console.log(deferred.promise.$$state.status); //1 

주석에서 언급했듯이 Angular 버전을 업그레이드 할 때 깨질 수 있으므로 권장하지 않습니다.


25
Angular 문서는 $$...속성을 사용해서는 안된다고 말합니다 . Angular의 최신 버전으로 업그레이드 할 때 위험 할 수 있습니다 ...
hgoebl

7
너무 나쁜 Angular는 실버 플래터에 개인 변수를 제공합니다. :(
Jackson


2
하지만 ... Angular는 inspect기능을 구현하지 않았습니다 . 따라서 Angular 개발자에게는 주스가 없습니다. Promise 프로토 타입에는 단순히 그것을 가지고 있지 않습니다.
Robert Koritnik

36

(Angular 소스를 수정하고 풀 요청을 제출하지 않고) 최선의 선택은 약속이 해결되었는지에 대한 로컬 플래그를 유지하는 것입니다. 관심있는 프라 미스를 설정할 때마다 재설정 then()하고 원래 프라 미스에 대해 완료로 표시하십시오 . 에서 $timeout then()원래 약속은 아직 여부를 확인할 경우 체크 플래그는 알고 있습니다.

이 같은:

var promiseCompleted = false;
promise.then(function(){promiseCompleted=true;})
$timeout(...).then(function(){if(!promiseCompleted)doStuff()})

Kris Kowal의 구현에는 promise의 상태를 확인하는 다른 방법이 포함되어 있지만 Angular의 구현에는 $q안타깝게도 이러한 방법이 포함되어 있지 않습니다.


9
여기서 .finally ()를 사용하는 것이 좋습니다. 위에 제공된 코드는 성공적으로 해결 된 경우에만 promiseCompleted 플래그를 true로 표시합니다.
Karanvir Kang

8

@shaunhusain이 이미 언급했듯이 가능하지 않은 것 같습니다. 하지만 필요하지 않을 수도 있습니다.

// shows stuff from 3s ahead to promise completetion, 
// or does and undoes it in one step if promise completes before
$q.all(promise, $timeout(doStuff, 3000)).then(undoStuff);

또는 더 좋을 수도 있습니다.

var tooSlow = $timeout(doStuff, 3000);
promise.always(tooSlow.cancel);

1

약속이 반환되었는지 확인해야하는 비슷한 문제가 있습니다. AngularJS의 $watch기능은 새 값과 이전 값이 모두 정의되지 않은 경우에도 페이지를 렌더링하는 동안 변경 사항을 등록하므로 외부 모델에 저장할 가치가있는 데이터가 있는지 확인해야합니다.

확실히 해킹이지만 이렇게합니다.

$scope.$watch('userSelection', function() {
  if(promiseObject.hasOwnProperty("$$v"){
    userExportableState.selection = $scope.userSelection;
  }
};

$$vAngularJS에서 사용하는 내부 변수 라는 것을 알고 있지만, 우리에게 해결 된 약속의 지표로 상당히 신뢰할 수있었습니다. AngularJS 1.2로 업그레이드하면 어떤 일이 일어날 지 누가 알겠습니까? :-/ $q1.2 문서에서 개선 사항에 대한 언급은 없지만 누군가 Q에 더 가까운 더 나은 기능 세트로 대체 서비스를 작성할 것입니다.


감사합니다. "비공개"회원을 사용하는 것보다 더 나은 옵션이 있습니다.
Jackson

0

정확한 시나리오는 모르지만 비동기 호출을 수행하고 약속을 생성 한 직후에 시간 제한을 적용하는 것이 더 일반적입니다.

상기 제공 setTimeout()진술하는 비동기 호출과 같은 이벤트 스레드에서, 당신은 경주 효과의 가능성에 대해 걱정할 필요는 없다. 자바 스크립트는 엄격하게 단일 스레드이므로 프라 미스의 .then()콜백은 이후 이벤트 스레드에서 발생하도록 보장됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.