> 웹 프론트엔드 > JS 튜토리얼 > JavaScript의 비동기 프로그래밍을 단계별로 이해해 보세요.

JavaScript의 비동기 프로그래밍을 단계별로 이해해 보세요.

青灯夜游
풀어 주다: 2021-06-18 09:50:18
앞으로
1380명이 탐색했습니다.

이 글에서는 JavaScript의 비동기 프로그래밍을 소개합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.

JavaScript의 비동기 프로그래밍을 단계별로 이해해 보세요.

Asynchronous는 비동기를 의미합니다...

이 섹션은 다소 지루할 수 있지만 JavaScript에서 매우 중요한 개념이므로 반드시 배워야 합니다.

목적

  • 개발 효율성을 높이고 유지 관리가 쉬운 코드 작성

질문 소개

  • 요청할 때 페이지가 멈추는 이유는 무엇인가요? ?
$.ajax({
  url: "www.xx.com/api",
  async: false, // true
  success: function(result) {
    console.log(result);
  },
});
로그인 후 복사
  • 데이터는 업데이트되는데 DOM은 업데이트되지 않는 이유는 무엇인가요? ?
// 异步批量更新DOM(vue-nextTick)
// <p id="app">{{num}}</p>
new Vue({
  el: "#app",
  data: {
    num: 0,
  },
  mounted() {
    let dom = document.getElementById("app");
    while (this.num !== 100) {
      this.num++;
    }
    console.log("Vue num=" + this.num, "DOM num=" + dom.innerHTML);
    // Vue num=100,DOM num=0
    // nextTick or setTimeout
  },
});
로그인 후 복사

비동기가 발생하는 이유

원인: 단일 스레드(한 시점에 한 가지 작업만 수행됨), 브라우저의 JS 엔진은 단일 스레드입니다.

단일 스레드는 JS 엔진에 IavaScript 코드를 해석하고 실행하는 스레드가 하나만 있다는 것을 의미합니다. 이를 메인 스레드라고 부를 수도 있습니다.

소위 단일 스레드는 한 번에 하나의 작업만 완료할 수 있음을 의미합니다. 여러 작업이 있는 경우 다음 작업이 실행되기 전에 이전 작업이 완료되어야 합니다.

먼저 브라우저 커널의 스레드 다이어그램을 살펴보세요.

JavaScript의 비동기 프로그래밍을 단계별로 이해해 보세요.

그 중에서 렌더링 스레드와 JS 스레드는 상호 배타적입니다.

DOM 노드를 수정하는 기능과 삭제하는 기능이 동시에 있다고 가정해 보겠습니다. 여러 스레드가 있는 경우 두 스레드가 동시에 실행되면 반드시 교착 상태가 발생하게 됩니다. 문제.

JS가 싱글 스레드로 설계된 이유는 브라우저의 특수한 환경 때문입니다.

단일 스레드의 장점과 단점:

이 모드의 장점은 구현이 비교적 간단하고 실행 환경도 비교적 간단하다는 것입니다. 단점은 하나의 작업에 시간이 오래 걸리면 후속 작업을 반드시 수행해야 한다는 것입니다. 대기 상태가 되어 전체 프로그램 실행이 지연됩니다. 일반적인 브라우저 무응답(일시 중단)은 장시간 실행되는 특정 Javascript 코드 조각(예: 무한 루프)으로 인해 발생하는 경우가 많습니다. 이로 인해 전체 페이지가 이 위치에 멈춰 다른 작업을 수행할 수 없게 됩니다.

일반적인 막힘(무한 루프):

while (true) {}
로그인 후 복사

JS는 원래 브라우저에서 실행되는 스크립트 언어로 설계되었기 때문에 너무 복잡하게 만들고 싶지 않아서 단일 스레드로 설계했습니다. 즉, one 그 시점에서는 딱 한 가지만 할 수 있습니다.

단일 스레드 차단을 해결이러한 단점을 해결하려면 비동기가 생성됩니다.

라면을 먹는 예를 들어보세요:

  • 동기식: 라면 구입 => 물 끓이기(멍하니 쳐다보기) => 면 요리하기 => 라면 먹기
  • 비동기식: 라면 구입 => 물 끓이기(물을 끓인다) 주전자 벨 - 콜백) = "TV 시청 =" 국수 요리하기 (면이 준비되고 주전자가 울릴 것입니다 - 콜백) = "TV 시청 =" 끝나면 전화하세요 = "라면 먹기

TV 시청은 비동기 작업을 수행하면 주전자가 울리게 됩니다. 이는 콜백 함수입니다.

비동기 프로그래밍

JS의 대부분의 코드는 동기식으로 실행되며, 일부 기능만 비동기식으로 실행됩니다. 비동기식으로 실행되는 코드에는 비동기식 프로그래밍이 필요합니다.

비동기 코드

setTimeout(() => {
  console.log("log2");
}, 0);
console.log("log1");
// ?? log1 log2
로그인 후 복사

비동기 코드의 특징: 즉시 실행되지 않고, 나중에 특정 시점에 기다려서 실행해야 합니다.

동기 코드 비동기 코드
<script> 코드 <script>代码网络请求(Ajax)
I/O 操作定时器(setTimeout、setInterval)
渲染操作Promise(then)

async/await

回调函数

异步代码最常见的写法就是使用回调函数。

  • HTTP 网络请求(请求成功、识别后执行 xx 操作)
  • DOM 事件绑定机制(用户触发事件后执行 xx 操作)
  • 定时器(setTimeout、setInterval)(在达到设定时间后执行 xx 操作)
// 注意到click方法中是一个函数而不是一个变量
// 它就是回调函数
$("#btn_1").click(function() {
  alert("Btn 1 Clicked");
});
// 或者
function click() {
  // 它就是回调函数
  alert("Btn 1 Clicked");
}
$("#btn_1").click(click);
로그인 후 복사

回调函数的缺点也很明显,容易产生回调地狱:

JavaScript의 비동기 프로그래밍을 단계별로 이해해 보세요.

异步编程的三种方式

  • callback
function getOneNews() {
  $.ajax({
    url: topicsUrl,
    success: function(res) {
      let id = res.data[0].id;
      $.ajax({
        url: topicOneUrl + id,
        success: function(ress) {
          console.log(ress);
          render(ress.data);
        },
      });
    },
  });
}
로그인 후 복사
  • promise
function getOneNews() {
  axios
    .get(topicsUrl)
    .then(function(response) {
      let id = response.data.data[0].id;
      return axios.get(topicOneUrl + id);
    })
    .then((res) => {
      render(res.data.data);
    })
    .catch(function(error) {
      console.log(error);
    });
}
로그인 후 복사
  • async/await
async function getOneNews() {
  let listData = await axios.get(topicsUrl);
  let id = listData.data.data[0].id;
  let data = await axios.get(topicOneUrl + id);
  render(data.data.data);
}
로그인 후 복사

在线预览

预览地址:http://jsrun.net/s43Kp/embedded/all/light

问题??

如果多个异步代码同时存在,那么执行顺序应该是怎样的?那个先执行、那个后执行了?

宏任务和微任务

异步代码的划分,异步代码分宏任务和微任务。

네트워크 요청(Ajax) I/O 작업Timer(setTimeout, setInterval)렌더링 작업
宏任务(不着急)微任务(着急)
<script>

Promise(then)🎜🎜🎜🎜🎜🎜🎜async/await🎜🎜🎜🎜🎜🎜콜백 함수🎜🎜 🎜 비동기 코드를 작성하는 가장 일반적인 방법은 다음과 같습니다. 콜백 함수를 사용하세요. 🎜🎜🎜HTTP 네트워크 요청(요청이 성공하고 인식된 후 xx 작업 실행) 🎜🎜DOM 이벤트 바인딩 메커니즘(사용자가 이벤트를 트리거한 후 xx 작업 실행) 🎜🎜Timer(setTimeout, setInterval)(설정된 시간 이후 xx 실행) 에 도달) 작업) 🎜🎜
console.log("script start");
setTimeout(function() {
  console.log("timeout1");
}, 10);
new Promise((resolve) => {
  console.log("promise1");
  resolve();
  setTimeout(() => console.log("timeout2"), 10);
}).then(function() {
  console.log("then1");
});
console.log("script end");
로그인 후 복사
로그인 후 복사
🎜콜백 함수의 단점도 명백하며 콜백 지옥을 생성하기 쉽습니다: 🎜🎜🎜JavaScript의 비동기 프로그래밍을 단계별로 이해해 보세요.🎜🎜🎜비동기 프로그래밍의 세 가지 방법🎜🎜🎜🎜callback🎜🎜rrreee🎜🎜pro 미세🎜🎜rrreee🎜🎜 async/await🎜 🎜rrreee🎜🎜 온라인 미리보기🎜🎜🎜미리보기 주소: http://jsrun.net/s43Kp/embedded/all/light🎜🎜🎜질문이 있으신가요? ? 🎜🎜🎜여러 개의 비동기 코드가 동시에 존재하는 경우 실행 순서는 어떻게 되나요? 어느 것이 먼저 실행되고 어느 것이 나중에 실행됩니까? 🎜🎜🎜매크로 작업과 마이크로 작업🎜🎜🎜비동기 코드의 구분, 비동기 코드는 매크로 작업과 마이크로 작업으로 구분됩니다. ... 🎜🎜setTimeout/ setInterval🎜🎜🎜🎜🎜🎜🎜

事件循环(Event loop)

JavaScript의 비동기 프로그래밍을 단계별로 이해해 보세요.

执行顺序:

  • 执行整体代码<script>(宏任务)

  • 执行所有微任务

  • 执行一个宏任务

  • 执行渲染线程

  • 2->3->2->3...依次循环(在 2、3 步中又创建了新的宏、微任务)

重复从宏任务和微任务队列里拿出任务去执行。

总结

因为浏览器设计的原因,JS 线程和渲染线程互斥,所以 JS 线程被设计成了单线程。

因为单线程执行一些操作(如网络请求)时有堵塞的问题,所有产生了异步。

因为有了异步,所以产生了异步编程,从而有了回调函数。

因为回调函数写多了会产生回调地狱,所有又有了解决回调地狱的 Promise 写法

自 ES7 标准后有了比 Promise 更加优雅的写法 ———— async/await 写法,也是异步编程的最终解决方法。

因为 JS 的代码分为同步和异步代码,同步代码的执行顺序不必多说,自上而下的执行。

但是如果有多个异步的代码,他的执行顺序又是怎么的呢??

为了解决多个异步代码的执行顺序问了,有了事件循环(EventLoop),将异步任务区分为宏任务、微任务,依据规则依次执行。

至此 完!

练习

console.log("script start");
setTimeout(function() {
  console.log("timeout1");
}, 10);
new Promise((resolve) => {
  console.log("promise1");
  resolve();
  setTimeout(() => console.log("timeout2"), 10);
}).then(function() {
  console.log("then1");
});
console.log("script end");
로그인 후 복사
로그인 후 복사

写出 log 的输出结果,并说出理由。

更多编程相关知识,请访问:编程视频!!

위 내용은 JavaScript의 비동기 프로그래밍을 단계별로 이해해 보세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:segmentfault.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿