JavaScript 비동기 프로 그래 밍 사: Promise 에서 Async / Await 로 함수 되 돌리 기

29495 단어 JavaScript
요약: 비동기 프로 그래 밍 시 자바 스 크 립 트 와 Node. js 의 하 이 라이트 중 어떤 슬 픈 흑 역 사 를 가지 고 있 습 니까?
  • 원문: Async programming basics every JS developer should know in 2018
  • 번역자: Fundebug
  • 소 편 추천: Fundebug 는 JS, 위 챗 애플 릿, 위 챗 게임, Node. js 와 자바 오류 모니터링 을 제공 합 니 다.정말 좋 은 오류 감시 서비스 입 니 다. 많은 대기업 들 이 사용 하고 있 습 니 다.
    가 독성 을 확보 하기 위해 서 본 고 는 직역 이 아니 라 의역 을 채택 한다.또한 본 논문 의 저작권 은 원작 자 에 게 있 고 번역 은 학습 에 만 사용 된다.
    리 턴 함수
    쉽게 말 하면 리 셋 함수 (callback function) 는 다른 숙주 함수 에 인 자 를 주 는 함수 입 니 다.리 셋 함 수 는 숙주 함수 에서 실행 되 며, 실행 결 과 는 숙주 함수 에 되 돌려 줍 니 다.
    //  click                  
    $("body").click(function() {
        alert(`clicked on body`);
    });
    

    쉽 지 않 아 요?
    이제 우 리 는 게임 에서 득점 업 그 레이 드 를 모 의 하 는 반전 함 수 를 실현 합 니 다.
    // levelOne()     ,             
    // levelOne()      callback       ,         ,     callback        
    function levelOne(value, callback)
    {
        var newScore = value + 5;
        callback(newScore);
    }
    
    function startGame()
    {
        var currentScore = 5;
        console.log('Game Started! Current score is ' + currentScore);
        
        // levelOne()           
        levelOne(currentScore, function(levelOneReturnedValue)
        {
            console.log('Level One reached! New score is ' + levelOneReturnedValue);
        });
    }
    
    startGame();
    

    상기 코드 를 실행 하면 콘 솔 출력 은 다음 과 같 습 니 다.
    "Game Started! Current score is 5"
    "Level One reached! New score is 10"
    

    출력 이 있 음 을 알 수 있 습 니 다. levelOne () 내 코드 (var newScore = value + 5;) 를 실행 한 후에 야 리 셋 함수 의 코드 (console. log ('Level One reached! New score is' + levelOne Returned Value) 를 실행 할 수 있 습 니까?
    이 를 통 해 알 수 있 듯 이 리 셋 함 수 는 특정 코드 가 실 행 된 후에 실 행 될 수 있 습 니 다. 이러한 실행 체 제 는 실제 프로 그래 밍 에서 매우 유용 합 니 다. 시간 이 걸 리 는 코드 를 실행 할 때, 예 를 들 어 파일 을 읽 을 때, 전체 코드 를 막 지 않 고 다른 코드 를 계속 실행 할 수 있 습 니 다. 파일 읽 기 가 완료 되면 코드 에 연 결 된 파일 읽 기 리 셋 함수 입 니 다.자동 으로 실 행 됩 니 다.
    그러나 여러 등급 의 반전 함 수 를 사용 할 때 상황 이 매우 나 빠 집 니 다. 다음은 코드 예제 입 니 다.
    function levelOne(value, callback)
    {
        var newScore = value + 5;
        callback(newScore);
    }
    
    function levelTwo(value, callback)
    {
        var newScore = value + 10;
        callback(newScore);
    }
    
    function levelThree(value, callback)
    {
        var newScore = value + 30;
        callback(newScore);
    }
    
    function startGame()
    {
        var currentScore = 5;
        console.log('Game Started! Current score is ' + currentScore);
        levelOne(currentScore, function(levelOneReturnedValue)
        {
            console.log('Level One reached! New score is ' + levelOneReturnedValue);
            levelTwo(levelOneReturnedValue, function(levelTwoReturnedValue)
            {
                console.log('Level Two reached! New score is ' + levelTwoReturnedValue);
                levelThree(levelTwoReturnedValue, function(levelThreeReturnedValue)
                {
                    console.log('Level Three reached! New score is ' + levelThreeReturnedValue);
                });
            });
        });
    
    }
    
    startGame();
    

    상기 코드 를 실행 하면 콘 솔 출력 은 다음 과 같 습 니 다.
    "Game Started! Current score is 5"
    "Level One reached! New score is 10"
    "Level Two reached! New score is 20"
    "Level Three reached! New score is 50"
    

    levelThree () 는 levelTwo () 의 반전 함수 이 고, levelTwo () 는 levelOne () 의 반전 함수 입 니 다. 그러면 정확 한 실행 순 서 는 levelOne () > levelTwo () > levelThree () 입 니 다.
    만약 10 개의 반전 함수 가 끼 워 져 있다 면? 보기 만 해도 고 개 를 끄 덕 이 는 것 이 아 닙 니까? 이 문 제 는 이른바 반전 지옥 (callback hell) 입 니 다! 해법 이 있 습 니까? 다음 회 분 해 를 들 어 보 세 요!
    Promise
    JavaScript 는 * * ES6 (즉 ECMAScript 2015) * * 부터 Promise 를 지원 합 니 다. 쉽게 말 하면 Promise 는 비동기 작업 의 성공 이나 실 패 를 나타 내 는 특수 한 대상 이 며 비동기 작업 의 실행 결 과 를 되 돌려 줍 니 다.
    Promise 구조 함 수 를 사용 하여 promise 를 정의 합 니 다:
    //       ,  resolve  ;    reject  
    var promise = new Promise(function(resolve, reject)
    {
        if ( /* everything turned out fine */ )
        {
            resolve("Stuff worked!");
        }
        else
        {
            reject(Error("It broke"));
        }
    });
    

    우 리 는 앞에서 지옥 으로 돌아 간 예 를 Promise 로 고 쳤 다.
    function levelOne(value)
    {
        var promise, newScore = value + 5;
        return promise = new Promise(function(resolve)
        {
            resolve(newScore);
        });
    }
    
    function levelTwo(value)
    {
        var promise, newScore = value + 10;
        return promise = new Promise(function(resolve)
        {
            resolve(newScore);
        });
    }
    
    function levelThree(value)
    {
        var promise, newScore = value + 30;
        return promise = new Promise(function(resolve)
        {
            resolve(newScore);
        });
    }
    
    var startGame = new Promise(function(resolve, reject)
    {
        var currentScore = 5;
        console.log('Game Started! Current score is ' + currentScore);
        resolve(currentScore);
    });
    
    // startGame         then  ,      levelOne  
    startGame.then(levelOne)
        .then(function(result)
        {
            // result levelOne      
            console.log('You have reached Level One! New score is ' + result);
            return result;
        })
        .then(levelTwo)
        .then(function(result)
        {
            console.log('You have reached Level Two! New score is ' + result);
            return result;
        })
        .then(levelThree)
        .then(function(result)
        {
            console.log('You have reached Level Three! New score is ' + result);
        });
    

    상기 코드 를 실행 하면 콘 솔 출력 은 다음 과 같 습 니 다.
    "Game Started! Current score is 5"
    "Level One reached! New score is 10"
    "Level Two reached! New score is 20"
    "Level Three reached! New score is 50"
    

    리 셋 함 수 는 포 함 된 방식 으로 levelOne (), levelTwo (), levelThree () 를 순서대로 호출 하고 Promise 는 then 을 사용 하여 연결 합 니 다.
    리 셋 함수 에 비해 Promise 코드 는 가 독성 이 높 고 코드 의 실행 순 서 는 일목요연 하 다.
    Promise 가 자 바스 크 립 트 비동기 프로 그래 밍 의 종점 인가? 물론 아니 지!
    Async/Await
    JavaScript 는 * * ES8 (즉 ECMAScript 2017) * * 부터 Async / Await 를 지원 합 니 다. Promise 함 수 를 동기 화 하 는 방식 으로 호출 하여 비동기 코드 의 가 독성 을 높 일 수 있 습 니 다.
    본질 적 으로 Async / Await 는 Promise 의 문법 설탕 을 기반 으로 동기 화 된 방식 으로 비동기 코드 를 쓸 수 있 습 니 다. 그러나 이 때문에 Async / Await 를 얕 보지 마 세 요. 동기 화 된 방식 으로 비동기 코드 를 쓰 는 것 은 매우 강력 합 니 다.
    함 수 를 정의 할 때 그 앞 에 async 키 워드 를 추가 하면 함수 에서 await 를 사용 할 수 있 습 니 다. await 가 Promise 일 때 코드 는 차단 되 지 않 은 방식 으로 계속 실 행 됩 니 다. Promise 가 resolve 에 성공 하면 await 문 구 는 실행 이 끝나 고 resolve 의 값 을 가 져 옵 니 다. Promise 가 실 패 했 을 때 reject 가 실 패 했 을 때 await 문 구 는 오류 가 발생 합 니 다.
    우 리 는 다시 async / await 로 이전의 예 를 고 칩 니 다.
    function levelOne(value)
    {
        var promise, newScore = value + 5;
        return promise = new Promise(function(resolve)
        {
            resolve(newScore);
        });
    }
    
    function levelTwo(value)
    {
        var promise, newScore = value + 10;
        return promise = new Promise(function(resolve)
        {
            resolve(newScore);
        });
    }
    
    function levelThree(value)
    {
        var promise, newScore = value + 30;
        return promise = new Promise(function(resolve)
        {
            resolve(newScore);
        });
    }
    
    //   aysnc       await  
    async function startGame()
    {
        var currentScore = 5;
        console.log('Game Started! Current score is ' + currentScore);
        currentScore = await levelOne(currentScore);
        console.log('You have reached Level One! New score is ' + currentScore);
        currentScore = await levelTwo(currentScore);
        console.log('You have reached Level Two! New score is ' + currentScore);
        currentScore = await levelThree(currentScore);
        console.log('You have reached Level Three! New score is ' + currentScore);
    }
    
    startGame();
    

    상기 코드 를 실행 하면 콘 솔 출력 은 여전히 다음 과 같 습 니 다.
    "Game Started! Current score is 5"
    "Level One reached! New score is 10"
    "Level Two reached! New score is 20"
    "Level Three reached! New score is 50"
    

    갑자기 코드 의 가 독성 이 많이 향상 되 었 습 니 다! 물론, async / await 의 신기 한 점 은 여기에 그 치지 않 습 니 다. async / await 의 오류 처리 가 매우 편리 합 니 다. 동기 코드 와 비동기 코드 를 같은 try.. catch... 문구 에 쓸 수 있 기 때 문 입 니 다. async / await 코드 를 사용 하 는 것 이 더욱 편리 합 니 다. Promise 를 사용 할 때, 우 리 는 정지점 을 설정 할 수 없습니다. async / await 코드 는 마치동기 코드 처럼 정지점 을 설정 합 니 다.
    레 퍼 런 스
  • 재 구성: Promise 에서 Async / Await
  • Async / Await 는 이렇게 JavaScript 코드 를 간소화 합 니 다
  • Async / Await 가 Promise 를 대체 하 는 6 가지 이유
  • Fundebug 에 대하 여
    Fundebug 는 JavaScript, 위 챗 애플 릿, 위 챗 애플 릿, Node. js, Java 실시 간 BUG 모니터링 에 전념 하고 있 습 니 다. 2016 년 쌍십일 정식 출시 이후 Fundebug 는 누적 5 억 + 오류 사건 을 처리 하여 많은 유명 사용자 들 의 인정 을 받 았 습 니 다. 무료 시용 을 환영 합 니 다!

    좋은 웹페이지 즐겨찾기