2017-10-17 6 views
2

약속 체인을 async/await으로 리팩터링하려고하지만 Typescript가 입력에 대해 불평하고 있습니다.Typescript가 async/await가 약속에 싸여있는 값을 반환한다고 생각하는 이유는 무엇입니까?

TS2322 : 유형 'IHttpPromiseCallbackArg < IResp은>'

나는 await 정기적 값이 아니라 약속을 돌려 줄 알았는데 ... 'IResp'을 입력 할 양도 할 수 없습니다. 내가 잘못? 그렇다면 원하는 코드를 컴파일 할 수 있도록 입력을 어떻게 할당합니까?

.then 콜백의 첫 번째 인수와 동일한 값이 반환 될 것이라고 생각했습니다. 내가 잘못?

오래된 코드 :

handleSubmit(form) { 
    const params = this.getParams(form); 

    this.myAsyncRequest(params) 
     .then((resp:IResp) => this.processResp(resp)) 
     .catch((e:IServerError) => this.handleError(e)); 
} 

원하는 새로운 코드 : 나는 myAsyncRequest에서 반환 형식을 제거하면 원하는 코드는 여전히 나누기

async handleSubmit(form) { 
    const params = this.getParams(form); 

    try { 
     const resp:IResp = await this.myAsyncRequest(params); //typing error with "const resp:IResp" 
     this.processResp(resp); 
    } catch (e:IServerError) { 
     this.handleError(e); 
    } 
} 

; Typescript는 AngularJS 라이브러리에서 직접 추측합니다. 나는 CONST RESP 선언에서 "IResp"를 제거하면

myAsyncRequest(params:IParams):IHttpPromise<IResp> { 
    return $http.post('blah', data); 
} 

, processResponse는 ... IHttp < IResp이> 같지 IResp을한다는 것을

processResp(resp:IResp) { 
    //do stuff 
} 
+0

최소한의 완전한 예제를 제공해주십시오. – NineBerry

+3

IHttpPromiseCallbackArg 유형은 약속이 아닙니다. 이것은 이미 함수 호출의 실제 결과입니다. http://definitelytyped.org/docs/angular-translate--angular-translate/interfaces/ng.ihttppromisecallbackarg.html – NineBerry

+0

을 참조하십시오. 제 질문에 대한 단어를 다시 말할 수 있습니다. "나는''''await''이 첫 번째 인수와 같은 값을 반환 할 것이라고 생각했습니다. '.then' 콜백에서. 나는 틀린가? " – user2954463

답변

3

"나는 콜백의 첫 번째 인수와 동일한 값을 반환 할 것이라고 생각합니다. 내가 잘못 했습니까?"

아니요, 정말로 옳습니다. 그러나. 콜백의 첫 번째 인수가 무엇인지에 대해서는 틀린 것입니다.

IHttpPromise<IResp>을 반환하려면 myAsyncRequest을 정의하십시오. 그러나 IHttpPromise<T>IPromise 다음과 같은 방법을 상속으로 정의된다 :

type IHttpPromise<T> = IPromise<IHttpPromiseCallbackArg<T>>; 

그래서, IHttpPromise<T> 유형 T의 실제 데이터가 IHttpPromiseCallbackArg<T>data 속성에있는 IHttpPromiseCallbackArg<T> 등을 반환하는 약속입니다.

그래서, 우리는 문제에서 볼 수있는 이전 코드 변종 : myAsyncRequestIHttpPromise를 반환하도록 정의 될 때

handleSubmit(form) { 
    const params = this.getParams(form); 

    this.myAsyncRequest(params) 
     .then((resp:IResp) => this.processResp(resp)) 
     .catch((e:IServerError) => this.handleError(e)); 
} 

실제로 타이프에서 오류없이 컴파일해서는 안된다.

노하우 수정이 :

async handleSubmit(form) { 
    const params = this.getParams(form); 

    try { 
     const httpResp:IHttpPromiseCallbackArg<IResp> = await this.myAsyncRequest(params); 
     const resp: IResp = httpResp.data; 
     this.processResp(resp); 
    } catch (e:IServerError) { 
     this.handleError(e); 
    } 
} 

참고 : 각도의 최신 유형 정의에서 유형 IHttpPromiseCallbackArg<T> 실제로 IHttpResponse<T>라고합니다.

코드에 IRespIHttpResponse<Something>으로 정의 했습니까? 그런 다음 이전 이름 ​​인 IHttpPromiseCallbackArg과 충돌합니다. 그런 다음 새 이름을 사용하는 최신 유형 정의를 DefinitelyTyped에서 가져옵니다. 또한 myAsyncRequest의 정의를 다음으로 변경해야합니다.

myAsyncRequest(params:IParams):IHttpPromise<Something> { 
-2

await가 실제로 해결 기다리고 있습니다 않는 포함하는 라인을 불평 값 -하지만 함수 자체가 비동기 적이기 때문에 (기다리고있는 모든 것을 허용하기 위해), 당신은 약속을 되 찾는다.

예 ... 아래의 코드에서 당신은 y 다시 일반 숫자로 (비록 delay 반환 약속을) x을 사용할 수 있습니다 - 당신이하는 것처럼 당신이 더 사용할 수 있도록 그래서 당신이 기다리고있는 모든 재료가 해결 그것이 동기라면.

약속을 반환하는 것처럼 보이지 않는 비동기 함수는 이제 않습니다.

"약속을 뒤집을 것"으로 보이기 때문에 혼란스러워 할 수 있습니다.하지만 then을 최상위 수준으로 변경하면 (다른 비동기 함수를 호출하는 등의 비동기 함수가있을 수 있습니다).

function delay(ms: number) { 
    return new Promise<number>(function(resolve) { 
     setTimeout(() => { 
      resolve(5); 
     }, ms); 
    }); 
} 


async function asyncAwait() { 
    let x = await delay(1000); 
    console.log(x); 

    let y = await delay(1000); 
    console.log(y); 

    return 'Done'; 
} 

asyncAwait().then((result) => console.log(result)); 
+0

그래서 하루가 끝날 때, 나는 여전히 .then을 어딘가에 불러야 만 하는가? – user2954463

+0

당신은 여전히 ​​맨 위에'then'을 호출해야 할 수도 있습니다 (어떤 경우에는 함수를 다른 곳으로 전달할 때 필요하지 않습니다). – Fenton

+1

downvote는 무엇입니까? 답변 개선을위한 권장 사항은 무엇입니까? –