콜백 지옥
JavaScript 프로그래머의 경우 콜백을 처리하는 것은 집이 아니지만 너무 깊은 레벨을 가진 콜백을 처리하는 것은 그다지 아름답 지 않습니다. 다음 샘플 코드 스 니펫은 3 층 콜백을 사용한 다음 더 많은 장면을 위해 뇌를 보충합니다. 그것은 단순히 신맛입니다. 이것은 전설적인 콜백 지옥입니다.
getDirectories (function (dirs) {getFiles (dirs [0], function (filts) {getContent (파일 [0], 함수 (fille, content) {console.log ( 'filename :', file); confole.log (content);});}); 함수 getDirectories (Callback) {settimeout (function () {Callback ([ '/home/ben']);}, 1000);} 함수 getfiles (dir, callback) {settimeout (function () {[dir + '/test1.txt', dir + '/test2.txt'); settimeout (function () {콜백 (파일, 'content');}, 1000)}해결책
생태계에는 Bluebird, Q 등과 같은 콜백 지옥 문제를 처리 할 수있는 많은 비동기 솔루션이 있습니다.이 기사는 ECMAScript 6/7 사양의 비동기 프로그래밍 지원에 중점을 둡니다.
ES6 약속
약속은 비동기 프로그래밍을위한 솔루션이며 콜백 지옥 문제를 해결하기위한 강력한 도구입니다.
Dojo 프레임 워크가 dojo.deferred의 기능을 추가했을 때 2007 년 JavaScript 생태계에서 약속이 주류로 받아 들여졌습니다. Dojo.Deferred의 인기로 2009 년 Kris Zyp은 CommonJS 약속/사양을 제안했습니다. 그 후, Q.JS, FuturesJS 등을 포함하여 많은 수의 약속 구현이 생태계에 나타났습니다. 물론, 약속의 인기는 주로 jQuery의 존재로 인한 것이지만 jQuery는 CommonJS 약속/사양을 완전히 준수하지 않습니다. 보시다시피 ES 6 사양에는 약속이 포함됩니다.
약속은 MDN에서 다음과 같이 설명됩니다.
Promise Object는 반환 값의 대리인이며, 약속 객체가 생성 될 때 알 수 없습니다. 비동기 작업의 성공 또는 고장을위한 취급 방법을 지정할 수 있습니다. 이렇게하면 비동기 메소드가 동기 방법과 같은 값을 반환 할 수 있습니다.
다음 코드는 약속을 통해 구현 된 "콜백 지옥"섹션의 예입니다. 이 코드는 간결하게 보이지 않지만 기존의 계층 콜백에 비해 크게 개선되었으며 코드는 유지 가능하고 읽을 수 있습니다.
getDirectories (). 그런 다음 (function (dirs) {return getFiles (DIRS [0]);}). 그런 다음 (function (files) {return getContent (files [0]);}). 그런 다음 (function (val) {console.log ( 'filename :', val.file); console.log (val.content);}); function getDirectories () {return new Promise (function (resolve, Reject) {settimeout (function () {resolve ([ '/home/ben']);},}, 1000);} 함수 getFiles (dir) {return new Promise (resolve, refort (resolve) {dir + '/test1.txt1.txt1.txt1.txt1.txt1. '/test2.txt']);ES6 생성기
약속의 구현은 충분히 간단하지 않으며, 우리는 여전히 더 나은 선택이 필요하며 Co는 선택 중 하나입니다. CO는 발전기를 기반으로 한 비동기식 유량 컨트롤러입니다. CO를 이해하기 전에 먼저 생성기를 이해해야합니다. C#에 익숙한 학생들은 모두 C# 2.0 버전이 생성기를 반복하기 위해 수율 키워드를 소개한다는 것을 이해해야합니다. ES 6 발전기는 C#과 유사하며 수율 구문 설탕을 사용하며 내부적으로 상태 기계를 구현합니다. 구체적인 사용은 MDN 문서 함수* 섹션을 참조하고 생성기에 대한 심도있는 이해를 위해 합금 팀 블로그를 참조하십시오. CO를 사용하여 ES6 생성기를 영리하게 결합하고 ES6은 비동기 호출을보다 조화로운 것으로 약속합니다.
co (function* () {var dirs = getDirectories (); var files = getfiles (dirs [0]); var contentval = getContent (files [0]); console.log ( 'filename :', contentVal.file); console.log (contentVal.content);});CO는 매우 영리하며 핵심 코드는 다음 예를 단순화 할 수 있습니다. 일반적인 아이디어는 상태가 완료 될 때까지 재귀 횡단 생성기를 사용하는 것입니다. 물론 CO는 더 많은 일을합니다.
Rungenerator (); function* run () {var dirs = getDirectories (); var 파일 = 수율 getFiles (DIRS [0]); var contentVal = 수율 getContent (파일 [0]); console.log ( 'filename :', contentVal.File); console.log (contentVal.Content);} 함수 rungenerator () {var gen = run (); 함수 go (result) {if (result.done) return; result.value.then (function (r) {go (gen.next (r));}); } go (gen.next ());}ES7 비동기/기다립니다
ES6 Generator는 정말 좋지만 타사 라이브러리의 지원이 필요하다는 것은 유감입니다. 좋은 소식은 ES 7이 비동기 통화 문제를 완벽하게 해결하기 위해 비동기/대기 키워드를 소개한다는 것입니다. .NET은 한 발 앞서 있으며 .NET Framework 4.5가 이미 처음으로 지원되었습니다.
향후 코드는 다음과 같이 작성됩니다.
run (); async function run () {var dirs = getDirectories (); var files = getfiles (dirs [0]); var contentVal = getContent (파일 [0]); console.log ( 'filename :', contentVal.File); console.log (contentVal.Content);}결론적으로
클래식 콜백 비동기식 프로그래밍 방법에서 ES6 Promise 사양에 의한 비동기 프로그래밍의 개선, ES 생성기와 공동체의 우아한 처리 및 ES7 Async/Await의 완벽한 결말에 이르기까지 ECMAS 스크립트가 왜 이러한 기능을 가지고 있는지, 무엇이 해결되는지 이해할 수 있으며 Javascript Asynchronous Programming의 개발을보다 명확하게 볼 수 있습니다.