>  기사  >  웹 프론트엔드  >  javascript 비동기 프로그래밍_javascript 기술에 대한 자세한 토론

javascript 비동기 프로그래밍_javascript 기술에 대한 자세한 토론

WBOY
WBOY원래의
2016-05-16 15:14:341062검색

비동기 프로그래밍으로 인한 문제는 클라이언트 측 Javascript에서는 명확하지 않지만 서버 측 Javascript가 점점 더 널리 사용됨에 따라 많은 수의 비동기 IO 작업이 이 문제를 명백하게 만듭니다. 이 문제를 해결하는 방법에는 여러 가지가 있습니다. 이 문서에서는 그 중 일부에 대해 설명하지만 깊이 다루지는 않습니다. 누구나 자신의 상황에 맞춰 자신에게 맞는 방법을 선택하면 된다.

이 글에서는 js의 비동기 프로그래밍을 구체적으로 소개합니다

1 비동기 이벤트 정보

이벤트는 JavaScript에서 가장 중요한 기능이며 nodejs는 js의 비동기 특성을 활용하도록 설계되었습니다. 그럼 여기서 이벤트 메커니즘에 대해 이야기해 보겠습니다.

js 파일에서 특정 함수를 실행하려면 두 가지 방법이 있습니다. 하나는 foo()와 같이 직접 호출하는 것이고, 두 번째는 이벤트를 사용하여 이를 트리거하는 것입니다. setTimeout 함수와 onready 속성에 전달하는 등 콜백 함수를 호출합니다.

1. setTimeout 함수의 이벤트는 비동기식입니다
setTimeout은 본질적으로 지연 시간이 만료될 때 트리거되는 비동기 이벤트입니다. 그러나 때때로(사실 대부분의 경우) 지정된 지연 시간에 따라 실행되지 않습니다. 아래 코드

  var start = new Date();
  setTimeout(function() {
   console.log('settimeout1:',new Date()-start);
  }, 500);
  while (new Date() - start < 1000) {
   console.log('in while');
  }
  document.getElementById('test').addEventListener('click', function(){
   console.log('test:',new Date()-start);
  }, false)
  for(var i=0;i<10000;i++){
   console.log('in for');
  }
  setTimeout(function(){
   console.log('settimeout2: ',new Date()-start);
  },1000);
  /* 10214
  in while
  index.jsp (第 19 行)
  10000
  in for
  index.jsp (第 25 行)
  settimeout1: 2263
  index.jsp (第 16 行)
  settimeout2: 3239
  index.jsp (第 28 行)
  test: 10006
  index.jsp (第 22 行)
  test: 28175
  index.jsp (第 22 行)
  test: 28791
  index.jsp (第 22 行)
  test: 28966
  index.jsp (第 22 行) */

일반적인 이해에 따르면 지연 함수는 500밀리초 후에 while 루프를 중단해야 하지만 실제로는 그렇지 않습니다. 게다가 while 루프와 for 루프 중에 div를 클릭하면 테스트가 즉시 출력되지 않습니다. 주어진 설명은 다음과 같습니다:

a) 이벤트 대기열. setTimeout 함수가 호출되면 전달된 콜백 함수가 이벤트 큐에 추가되고(이벤트가 초기화되어 메모리에 있음), 더 이상 코드를 실행할 수 없을 때까지 후속 코드가 계속 실행됩니다. 정상적인 실행 흐름이 아닙니다)(이벤트 함수와 같은 비동기 콘텐츠 제외), 적합한 이벤트가 이벤트 큐에서 튀어나와 실행됩니다.

b) js는 단일 스레드이므로 스레드가 유휴 상태가 될 때까지 이벤트 핸들러가 실행되지 않습니다.

2 일반 이벤트의 비동기성은 setTimeout과 유사합니다
두 개의 Promise 객체와 Deferred 객체

1. 약속
Promise는 ajax와 같은 비동기 프로그래밍에서 콜백 함수가 너무 많이 중첩되어 코드를 모호하고 이해하기 어렵게 만드는 문제에 대한 솔루션입니다. 특히 nodejs에서는 비동기가 어디에나 있습니다. 다양한 프레임워크가 promise를 구현합니다. 다음은 jquery의 promise API입니다.

약속의 구현 원칙은 여기서 다루지 않습니다. 이 원칙은 다른 장에서 소개하겠습니다.

전통적인 Ajax 비동기 프로그래밍은 다음과 같이 작성됩니다(jquery1.5 이전).

$.get('url', function(){
 $.get('url1', function(){
  $.get('url2', function(){

  }, 'json');
 }, 'json');
}, 'json');

이와 같은 코드를 작성하면 개발 및 유지 관리에 큰 어려움이 따릅니다. 다행히도 jquery1.5에 Promise가 도입된 후에는 다음과 같이 작성할 수 있습니다.

 $.ajax( "example.php" )
.done(function() { alert("success"); })
.fail(function() { alert("error"); })
.always(function() { alert("complete"); });

이제 훨씬 더 단순해 보입니다.

2.지연 객체

var nanowrimoing = $.Deferred();
var wordGoal = 5000;
nanowrimoing.progress(function(wordCount) {
var percentComplete = Math.floor(wordCount / wordGoal * 100);
$('#indicator').text(percentComplete + '% complete');
});
nanowrimoing.done(function(){
$('#indicator').text('Good job!');
});

3. 작업자 객체와 멀티스레딩

4. 비동기 스크립트 로딩

1. 페이지 내 기존 스크립트의 위치
스크립트는 크게 차단과 비차단이라는 두 가지 범주로 나뉩니다. 여기서 차단이란 차단을 실행하는 것이 아니라 차단을 로드하는 것을 의미합니다.

<!DOCTYPE html>
<html>
<head>
<script src="headScript"></script>
<script defer src="deferredScript"></script>
</head>
<body>
 <script async defer src="chatWidget"></script>
 <script async defer src="asyncScript"></script>
</body>
</html>

위의 코드 부분은 페이지 내 스크립트 위치와 관련하여 비교적 표준적인 것입니다. 1. 기존의 수정되지 않은 headScript는 브라우저가 위에서 아래로 JavaScript를 해석하고 실행하므로 이 일부 스크립트 파일은 DOM은 실행이 완료되기 전에 렌더링되지 않지만 head 태그의 CSS는 로드됩니다. 2. defer 속성이 있는 스크립트는 DOM이 렌더링되는 동시에 로드되지만, 불행히도 모든 브라우저가 defer 속성을 지원하는 것은 아니므로 jquery(함수)가 생성됩니다. . 3. async 속성과 defer 속성이 모두 존재하는 경우 defer는 async를 재정의하지만 async만 제공되면 DOM 렌더링 중에 스크립트가 로드되어 실행됩니다.

2. 프로그래밍 가능한 스크립트 로딩
처음부터 js 파일을 페이지에 도입하지 않고 사용자 상호작용을 통해 js 스크립트를 동적으로 로드하는 경우 프로그래밍 방식으로 추가할 수 있습니다.

브라우저가 서버 스크립트를 얻는 방법에는 두 가지가 있습니다. Ajax는 eval 함수를 통해 이를 얻고 실행합니다. 두 번째 방법은 브라우저가 우리를 돕기 때문에 일반적으로 사용됩니다. HTTP 요청 및 평가 누출 범위를 생성합니다.

var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.src = '/js/feature.js';
head.appendChild(script);
script.onload = function() {
// 现在可以调用脚本里定义的函数了
}

위 내용은 이 글의 전체 내용입니다. JS 비동기 프로그래밍을 배우는 모든 분들께 도움이 되기를 바랍니다.

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