나는 일반적으로 then()
약속을 사용할 때 호출 및 체인 동작과 함께 연속 코드를 첨부한다는 것을 이해합니다 .
그러나 $timeout()
원래 promise가 아직 완료되지 않은 경우에만 UI 작업을 수행 할 수 있도록 promise 래핑 된 비동기 호출을 시작한 다음 3 초를 별도로 시작하고 싶습니다. (저는 연결이 느린 경우, 3G의 모바일 장치 등에서 만 발생할 것으로 예상합니다.)
약속이 주어지면 차단하거나 기다리지 않고 완료 여부를 확인할 수 있습니까?
답변
나는 이것이 Angular의 최신 버전에 추가되었다고 생각하지만 이제 약속에 $$ state 객체가있는 것 같습니다.
var deferred = $q.defer();
console.log(deferred.promise.$$state.status); // 0
deferred.resolve();
console.log(deferred.promise.$$state.status); //1
주석에서 언급했듯이 Angular 버전을 업그레이드 할 때 깨질 수 있으므로 권장하지 않습니다.
답변
(Angular 소스를 수정하고 풀 요청을 제출하지 않고) 최선의 선택은 약속이 해결되었는지에 대한 로컬 플래그를 유지하는 것입니다. 관심있는 프라 미스를 설정할 때마다 재설정 then()
하고 원래 프라 미스에 대해 완료로 표시하십시오 . 에서 $timeout
then()
원래 약속은 아직 여부를 확인할 경우 체크 플래그는 알고 있습니다.
이 같은:
var promiseCompleted = false;
promise.then(function(){promiseCompleted=true;})
$timeout(...).then(function(){if(!promiseCompleted)doStuff()})
Kris Kowal의 구현에는 promise의 상태를 확인하는 다른 방법이 포함되어 있지만 Angular의 구현에는 $q
안타깝게도 이러한 방법이 포함되어 있지 않습니다.
답변
@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);
답변
약속이 반환되었는지 확인해야하는 비슷한 문제가 있습니다. AngularJS의 $watch
기능은 새 값과 이전 값이 모두 정의되지 않은 경우에도 페이지를 렌더링하는 동안 변경 사항을 등록하므로 외부 모델에 저장할 가치가있는 데이터가 있는지 확인해야합니다.
확실히 해킹이지만 이렇게합니다.
$scope.$watch('userSelection', function() {
if(promiseObject.hasOwnProperty("$$v"){
userExportableState.selection = $scope.userSelection;
}
};
$$v
AngularJS에서 사용하는 내부 변수 라는 것을 알고 있지만, 우리에게 해결 된 약속의 지표로 상당히 신뢰할 수있었습니다. AngularJS 1.2로 업그레이드하면 어떤 일이 일어날 지 누가 알겠습니까? :-/ $q
1.2 문서에서 개선 사항에 대한 언급은 없지만 누군가 Q에 더 가까운 더 나은 기능 세트로 대체 서비스를 작성할 것입니다.
답변
정확한 시나리오는 모르지만 비동기 호출을 수행하고 약속을 생성 한 직후에 시간 제한을 적용하는 것이 더 일반적입니다.
상기 제공 setTimeout()
진술하는 비동기 호출과 같은 이벤트 스레드에서, 당신은 경주 효과의 가능성에 대해 걱정할 필요는 없다. 자바 스크립트는 엄격하게 단일 스레드이므로 프라 미스의 .then()
콜백은 이후 이벤트 스레드에서 발생하도록 보장됩니다.