async await, Promise, setTimeout 실행 순서

4469 단어
제목에서 본 진지:
[제목]
async function async1(){
   console.log('async1 start');
    await async2();
    console.log('async1 end')
}
async function async2(){
    console.log('async2')
}
console.log('script start');
setTimeout(function(){
    console.log('setTimeout')
},0);
async1();
new Promise(function(resolve){
    console.log('promise1');
    resolve();
}).then(function(){
    console.log('promise2')
});
console.log('script end')

답:
script start
async1 start
async2
promise1
script end
promise2
async1 end
setTimeout

관련 지식:
완일봉 선생님의 설명을 나는 더욱 이해하기 쉽다고 생각한다.
async 함수는 Promise 대상을 되돌려줍니다. 함수가 실행될 때 await를 만나면 먼저 되돌려주고 트리거된 비동기적인 작업이 끝날 때까지 기다린 다음에 함수 안의 뒤에 있는 문장을 실행합니다.라인을 양보하고 async 함수체를 뛰어넘었다는 뜻으로 이해할 수 있다
그리고 아래의 이 출력 순서는 우리가 예상한 것과 다르군요
async1 end
promise2

==async==
async function 성명은 AsyncFunction 대상을 되돌려주는 비동기 함수를 정의합니다.async 함수를 호출하면 Promise 객체가 반환됩니다.이 async 함수가 값을 되돌려줄 때 Promise의resolve 방법은 이 값을 전달하는 것을 책임집니다.async 함수가 이상을 던지면 Promise의reject 방법도 이 이상 값을 전달합니다.
그래서 아시다시피 async가 정의한 함수를 사용합니다. 호출되었을 때, 그 함수는 사실 Promise 대상입니다.
await 표현식 실행이 어떤 값을 되돌려줄지 다시 봅시다.
await
문법: [return_value] = await expression;표현식(express): Promise 객체 또는 기다릴 값입니다.반환값(return_value): Promise 객체의 처리 결과를 반환합니다.Promise 객체가 아닌 경우 값 자체를 반환합니다.
따라서await 조작부호 뒤의 표현식이 Promise일 때, 그 반환값은 실제적으로 Promise의 리셋 함수resolve의 매개 변수이다.
이 두 가지 일을 알게 된 후에 나는 또 두 마디 더 수다를 떨어야 한다.우리는 모두 Promise가 즉각 실행 함수라는 것을 알고 있지만, 그의 성공(또는 실패:reject)의 리셋 함수resolve는 비동기적으로 실행되는 리셋이다.resolve () 를 실행할 때, 이 작업은 리셋 대기열에 넣고, 호출 창고가 비어 있을 때 이벤트 순환이 다시 가져오기를 기다립니다.

문제 해결 방법:


async1이라는 함수를 실행할 때 우선'async1start'를 출력합니다. (이것은 더 말할 필요가 없습니다. async표현식이 정의한 함수도 즉시 실행됩니다.)
그리고 await async2()에 실행했는데 async2도 async가 정의한 함수임을 발견하고'console.log('async2')'를 직접 실행했습니다. 동시에 async2는 Promise를 되돌려 주었습니다. 중점을 둡니다. 이때 되돌아오는 Promise는 리셋 대기열에 넣고 기다립니다. await는 라인을 양보합니다.
그리고 new Promise에 실행합니다. 앞에서 promise가 바로 실행된다고 말했기 때문에 "promise 1"을 출력하고 Resolve에 실행할 때 Resolve 이 작업은 리셋 대기열에 넣습니다. (앞에서 수업을 잘 들어야 한다고 말했잖아요) 기다린 다음에 Promise에서 뛰어나와 계속 아래로 실행하고 "script end"를 출력합니다.
다음은 하이라이트다.동기화된 이벤트가 모두 순환되어 실행되었습니다. 호출 창고가 비어 있습니다. 그러면 이벤트 순환은 리셋 대기열에서 작업을 찾아 호출 창고에 계속 넣을 것입니다.
이때 얻은 첫 번째 작업은 바로 앞에 async1을 넣은 Promise입니다. Promise를 실행할 때 그의 진명천자 resolve 함수를 만났습니다. 중점을 긋습니다. 이 resolve는 작업 대기열에 넣어서 계속 기다린 다음에 다시 async1 함수를 뛰어넘어 다음 작업을 계속합니다.
다음에 찾은 다음 작업은 바로 앞에 new Promise가 넣은 Resolve를 리셋하는 것입니다. yohoo~ 이 Resolve는 호출 창고에 옮겨져 실행되고 "promise2"를 출력한 다음 다음 다음 작업을 계속 가져옵니다.
뒤의 일은 네가 이미 알아맞혔다고 믿는다. 그래, 호출 창고가 다시 비어 있다. 사건 순환은 다음 임무를 얻는다. 천신만고 끝에 드디어 차례가 온 그 Promise의resolve 리셋!!!그것을 실행합니다. (아무것도 인쇄할 수 없습니다. async2는 리턴이 없기 때문에 이resolve의 매개 변수는 undefined). 이 때 await가 정의한 이 Promise가 실행되고 결과를 되돌렸기 때문에 async1 함수 뒤에 있는 작업을 계속 수행할 수 있습니다. 그것이 바로 "console.log ('async1 end')"입니다.
그리고 동기화(여기 리셋은 동기화라고 할 수 있고, 때로는 겨우 비동기화라고 할 수 있습니다)의 실행이 끝났습니다. 대기 대기열의 타이머를 실행하고, setTimeout을 출력합니다.

총결산

  • 호출 창고
  • 이벤트 순환
  • 퀘스트 대기열
  • promise의 리셋 함수 실행
  • async 표현식의 반환값
  • await 표현식의 작용과 반환값

  • 대기열 작업 우선 순위:promise.Trick() > promise > setTimeout > setImmediate
    이로써 이 문제의 출력 결과 분석이 끝났습니다. 이런 실행 결과는 한마디로 요약할 수 있습니다. 먼저 동기화 코드를 실행하고 비동기화 코드를 만나면 먼저 대기열에 가입한 순서에 따라 비동기화 코드를 실행하고 마지막에 setTimeout 대기열의 코드를 실행합니다.
    원문 주소:https://lvdingjin.github.io/tech/2018/05/27/async-and-await.html

    좋은 웹페이지 즐겨찾기