ABOUT ME

In Manus Tuas Pater, Commendo Spiritum Meum

Today
Yesterday
Total
  • async/await
    JavaScript/입 속의 검은 잎 2022. 10. 5. 20:27

    처음 나를 애먹였던 것은 아마도 await 였다.

    몇가지 시시한 요인이 있다.

    1.어휘 뜻이 그냥 좀 딜레이를 두겠다는 것 같다, 2.그런데 사용 양상은 마치 딜레이를 없애고 다시 동기화시키는 것 같다. 

     

    좀 더 직관적으로 비동기처리를 할 수 있도록, 비동기적 과정을 표면상에서는 생략하도록 만들어진 것이, 

    오히려 비동기적 사고를 따라가려는 나에게 또다른 에러가 되었던 것 같다.

     

    하여튼 지금은 이렇게 이해한다.

    비동기처리를 위한 콜백함수도, 프로미스도, 그리고 저 await도, "오이디푸스"이다.

    다른 뜻이 아니라 자기 실현적 예언이라는 틀에서 그렇다.

    자기실현적인 콜백, 약속(promise), 잠깐만(await)의 예언적 순간들 말이다.

     

    이것은 서스펜스와 개연성의 원천이며 인류의 보편이기도 하다.

    그래서 남들은 쉽게 이해하는 await를 어렵게 이해하면서 알았다.

    코딩에도 서스펜스가 있구나.


     

    async 함수를 promise로 풀어서 쓰면 이렇다.

    다만 위의 async 함수는 resolve를, 아래의 promise는 reject를 리턴한다.

    async function asyncPrac() {
        return 'done!';
    }
    
    function promisePrac() {
        return new Promise((resolve, reject) => {
        reject('Error!');
        }); 
    }
    
    const result = asyncPrac();
    console.log(result); 			// Promise { 'done!' }
    
    const result2 = promisePrac();
    console.log(result2)			//Promise { <rejected> 'myError!' }
    
    
    
    //triggerUncaughtException(err, true /* fromPromise */);

     

    await는 비동기처리를 위한 연산자이지만, 비동기적 사고를 하지 않아도 되도록 만들어준다.

    아래 예제에서, 프로미스에러발생 함수는 await로 인해 스크립트의 순서대로 작동한다. 즉, 두번째 날짜 콘솔로그가 찍히지 않는다.

    await가 없었다면, 표면적으로는 비동기적인 결과를 마주했을 것이다.

    두 날짜 콘솔이 모두 찍히고, 이후 에러가 나는 상황.

    function 몇초후프로미스에러발생(sec){
        return new Promise((resolve,reject)=>{
            setTimeout(()=>{
                reject('error!');
            }, sec*1000);
        })
    }
    
    async function asyncPrac() {
        
        console.log(new Date()) // 2022-10-05T10:31:07.462Z // 이 타임스탬프는 정상적으로 찍힌다.
        await 몇초후프로미스에러발생(3) //await가 없었다면, 동기적인 스크립트의 시간은 3초의 딜레이를 지나쳐 갔을 것이다.
        console.log(new Date())   //때문에 이 두번째 타임스탬프도 찍혔을 것이다. 그리고 그 이후에야 에러가 찍힌다. 
                                  //await가 없었다면 말이다.
    }
    
    const result = asyncPrac();
    
    
    '''
    2022-10-05T10:53:21.781Z
    
    node:internal/process/promises:279
                triggerUncaughtException(err, true /* fromPromise */);
    '''
    function 몇초후프로미스에러발생(sec){
        return new Promise((resolve,reject)=>{
            setTimeout(()=>{
                reject('error!');
            }, sec*1000);
        })
    }
    
    async function asyncPrac() {
        
        console.log(new Date())
        try{
            await 몇초후프로미스에러발생(3)
        }catch(e){
            console.error(e);
        }
    
        console.log(new Date())
    }
    
    const result = asyncPrac();
    
    //2022-10-05T11:08:33.216Z
    //error!
    //2022-10-05T11:08:36.228Z

    그리고 역시 try catch 문으로 에러를 잡았다. 그러나 이 경우는 더 단순하게 해결할 수 있다.

     

    function 몇초후프로미스에러발생(sec){
        return new Promise((resolve,reject)=>{
            setTimeout(()=>{
                reject('error!');
            }, sec*1000);
        })
    }
    
    async function asyncPrac() {
        
        console.log(new Date())
        
            await 몇초후프로미스에러발생(3).catch(e => {console.error(e)})
            
        console.log(new Date())
    }
    
    const result = asyncPrac();
    
    //2022-10-05T11:08:33.216Z
    //error!
    //2022-10-05T11:08:36.228Z

    프로미스의 catch 메서드로 에러를 잡을 수도 있다. 

    다만, 이 경우는 사실 숨어있는 진실이 따로 있다.

     

    console.log(new Date())
        
            const result = await 몇초후프로미스에러발생(3).catch(e => {console.error(e)})
            console.log(result)
    console.log(new Date())
        
        
    //2022-10-05T11:11:32.028Z
    //error!
    //undefined
    //2022-10-05T11:11:35.042Z

    await 연산자의 결과를 따로 변수에 담아 콘솔에 찍어보면, undefined 이다.

     

    await의 대상은 3초짜리 에러폭탄이 아니라, 그 뒤의 catch 문이다.

    promise의 함수들은 같은 객체를 대상으로 체인을 이루지 않는다. 항상 새로운 pomise 인스턴스를 리턴해준다.

    그런데 여기서는 catch가 자신의 역할을 실행(execute) 하고 아무것도 리턴하지 않은 것이다.

    그래서 await는 undefined 라는 값을 냈다.

     

    앞에서 await는 자기실현적 예언이라고 했었다. 

    3초짜리 에러폭탄은 이미 해소되었고, 새로운 예언을 기다리고 있었는데, 예언이 발행되지 않은 것이다.

     

    'JavaScript > 입 속의 검은 잎' 카테고리의 다른 글

    클래스 호이스팅  (0) 2022.10.18
    클래스, super, 오버라이딩  (0) 2022.10.12
    promise catch error  (0) 2022.10.05
    try catch error  (1) 2022.10.05
    json 객체  (0) 2022.10.05
Designed by Tistory.