>  기사  >  웹 프론트엔드  >  Promise 실행 순서가 JavaScript의 예상과 일치하지 않는 이유는 무엇입니까?

Promise 실행 순서가 JavaScript의 예상과 일치하지 않는 이유는 무엇입니까?

Patricia Arquette
Patricia Arquette원래의
2024-10-25 08:01:28398검색

Why Doesn't the Order of Promise Execution Match Expectations in JavaScript?

JavaScript Promise의 실행 순서는 무엇입니까?

문제:

다음 스니펫은 JavaScript 사용을 보여줍니다. 약속하고 실행 순서가 흥미롭습니다.

<code class="javascript">Promise.resolve('A')
  .then(function(a){console.log(2, a); return 'B';})
  .then(function(a){
     Promise.resolve('C')
       .then(function(a){console.log(7, a);})
       .then(function(a){console.log(8, a);});
     console.log(3, a);
     return a;})
  .then(function(a){
     Promise.resolve('D')
       .then(function(a){console.log(9, a);})
       .then(function(a){console.log(10, a);});
     console.log(4, a);})
  .then(function(a){
     console.log(5, a);});
console.log(1);
setTimeout(function(){console.log(6)},0);</code>

결과는 실행 순서를 나타냅니다.

1
2 "A"
3 "B"
7 "C"
4 "B"
8 undefined
9 "D"
5 undefined
10 undefined
6

제기된 질문은 실행 순서가 1, 2가 아닌 이유입니다. , 3, 4..., 그리고 1, 2, 3, 4...의 기대치가 결과와 어떻게 다른가요?

답변:

댓글:

.then() 콜백에서 반환하지 않고 .then() 핸들러 내에서 Promise를 실행하면 상위 Promise와 동기화되지 않는 연결되지 않은 새로운 Promise 시퀀스가 ​​생성됩니다. 방법. 이는 일반적으로 버그로 간주되며 일반적으로 의도된 동작이 아니기 때문에 일부 Promise 엔진은 발생 시 경고를 발행합니다. 유효한 사용 사례는 오류나 동기화가 문제가 되지 않는 '실행 후 잊어버리기' 작업일 수 있습니다.

.then() 핸들러 내의 Promise.resolve() 프라미스는 상위 프라미스 체인과 독립적으로 실행되는 새로운 프라미스 체인을 생성합니다. 체인. AJAX 호출과 같은 실제 비동기 작업에서는 연결이 끊긴 독립적인 약속 체인에 대해 예측 가능한 동작이 없습니다. 완료 순서를 알 수 없는 4개의 AJAX 호출을 병렬로 실행하는 것과 같이 완료 시점은 불확실합니다. 제공된 코드에서 모든 작업은 동기식이므로 일관된 동작이 발생하지만 Promise의 설계 목적은 비동기식 실행이므로 이에 의존해서는 안 됩니다.

요약:

  1. 모든 .then() 핸들러는 현재 실행 스레드가 완료된 후 비동기적으로 호출됩니다. 이 일관성에는 타이밍 버그를 방지하기 위해 Promise.resolve().then(...)과 같이 동기적으로 해결된 약속이 포함됩니다.
  2. setTimeout()과 예약된 .then() 핸들러에는 지정된 순서가 없습니다. 사용된 구현에서는 보류 중인 setTimeout() 앞에 보류 중인 .then() 핸들러를 배치하지만 Promises/A 사양에서는 setTimeout() 이전이나 이후에 예약을 허용합니다.
  3. 독립적인 Promise 체인에는 예측 가능한 실행이 없습니다.
  4. 실행 순서가 중요한 경우 미세한 구현 세부 사항에 의존하는 레이스를 생성하지 마세요. 대신, 약속 체인을 연결하여 특정 순서를 강제합니다.
  5. '실행 후 잊어버리는' 시나리오가 아닌 이상 .then() 핸들러 내에서 독립적인 약속 체인을 생성하지 마세요.

라인별 분석:

  1. 초기 Promise 체인이 시작되고 .then() 핸들러가 연결됩니다. Promise.resolve()가 즉시 확인되므로 첫 번째 .then() 핸들러는 현재 JavaScript 스레드가 완료된 후에 실행되도록 예약됩니다. 후속 .then() 핸들러는 첫 번째 이후 최상위 체인에 있으며 첫 번째 핸들러가 완료된 후에만 실행됩니다.
  2. setTimeout()은 실행 스레드가 끝날 때 실행되고 타이머가 예약됩니다.
  3. 동기 실행이 완료된 후 이벤트 큐는 나머지 작업을 실행합니다.
  4. Line 1에 정의된 .then() 핸들러가 실행되고 '2 "A"'가 기록됩니다.
  5. 후속 .then() 핸들러가 호출되고, 현재 실행 스레드가 완료될 때 실행되도록 예약된 .then() 핸들러를 사용하여 새로운 독립 Promise 체인이 생성됩니다. 이 핸들러는 하위 체인의 .then() 핸들러가 실행되기 전에 '3 "B"'를 인쇄합니다. 그러면 '7 "C"'가 인쇄됩니다.
  6. 그런 다음 12행에 정의된 .then() 핸들러가 호출되고, 다시 새로운 Promise 체인이 생성되어 .then() 핸들러를 예약합니다. '4 "B"'가 이 핸들러에서 기록됩니다.
  7. 하위 체인에서 예약된 .then() 핸들러가 실행되어 '8 undefine'을 인쇄합니다.
  8. .then() 핸들러 19행에 정의된 코드가 이후에 호출되고 또 다른 독립적인 Promise 체인이 생성되어 .then() 핸들러를 예약합니다. 이 핸들러에서는 '5 undefine'이 출력됩니다.
  9. 마지막으로 15행에 정의된 .then() 핸들러가 호출되어 '10 undefine'이 출력됩니다.
  10. setTimeout()이 실행됩니다. last.

결론:

Promise.resolve()의 특정 순서가 부족하여 .then() 핸들러 내에서 약속이 실행될 뿐만 아니라 다양한 엔진에 대한 .then() 핸들러 스케줄링과 setTimeout()의 불확정성은 연결 약속을 통해 실행 순서를 제어하는 ​​것의 중요성을 강조합니다.

위 내용은 Promise 실행 순서가 JavaScript의 예상과 일치하지 않는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.