순서
Javascript에서 모두가 가장 많이 논의하는 것은 비동기 프로그래밍의 작동과 콜백의 다중 중첩을 방지하는 방법입니다. 비동기 작업 콜백이 많이 중첩되면 코드가 비대해질 뿐만 아니라 오류가 발생하기 쉽습니다. 잘 알려진 Promise, co 등 다양한 비동기 프로그래밍 솔루션도 지속적으로 제안되고 있습니다. 오늘 논의된 생성기와 수율은 비동기 프로그래밍과 관련되어 있으며 비동기 프로그래밍을 동기화하는 데 도움이 될 수 있습니다.
Generator 소개
Generator는 함수와 함수 이름 사이에 추가 *가 있다는 점을 제외하면 형식상 함수와 유사합니다. Yield 키워드는 Generator 내부에서 사용되어야 합니다. 예:
function * gen(){ var result1 = yield 'hello'; var result2 = yield 'world'; return result1 + result2; }
Generator 함수가 호출되면 함수 내부의 코드는 실행되지 않지만 next 메서드가 포함된 순회자가 반환됩니다. 다음 메서드가 실행될 때마다 Generator 함수 본문은 항복 문을 만날 때까지 실행을 시작하고 문을 실행한 후 여기서 일시 중지합니다. 사용법은 다음과 같습니다.
var g = gen(); g.next(1); //{value : 'hello', done : false} g.next(2); //{value : 'world', done : false} g.next(); //{value : 3, done: true} g.next(); //{value : undefined, done: true}
다음 메소드를 호출하면 객체가 반환됩니다. 이 객체에는 value와 done이라는 두 가지 속성이 포함되어 있습니다. done은 Generator 함수 본문이 실행되었는지 여부를 나타냅니다. 다음 메소드는 또한 항복 문의 반환 값으로 사용되고 후속 프로그램에서 사용될 수 있는 매개 변수를 허용합니다. 프로그램 실행이 완료되거나 return 문을 만나면 value는 함수 본문의 반환 값이고 done은 true가 됩니다. 이 시점에서 다음 메소드를 다시 실행하면 value는 정의되지 않고 done은 여전히 true입니다.
순회에서 Generator 적용
js에서는 for...of와 같은 문을 사용하여 순회할 수 있습니다. 이는 실제로 배열에 Generator traverser가 포함되어 있기 때문입니다. . 자체 정의된 객체에 순회자가 포함된 경우 for...of와 같은 순회 문을 통해 사용자 정의 개체를 순회할 수 있습니다. 이 반복자는 Symbol.iterator 속성에 저장됩니다.
var myArray = { 0: '你', 1: '的', 2: '名字', length: 3 }; myArray[Symbol.iterator] = function * (){ for(var i = 0; i < this.length; i++) { yield this[i]; } }; for(var item of myArray) { console.log(item); } //你 //的 //名字
비동기 프로그래밍에서 Generator 적용
Javascript의 핵심은 비동기 프로그래밍입니다. 각 비동기 작업은 실행 결과를 반환하는 콜백 함수를 제공합니다. 여러 작업이 있고 후자의 작업은 이전 작업의 결과에 따라 달라집니다. 콜백을 사용하는 경우:
step1(function(value1) { step2(value1, function(value2) { step3(value2, function(value3)) { //some code } }); })
이러한 코드는 콜백 중첩이 증가하면 프로그램을 매우 복잡하게 만듭니다. 이해하고 실수하기 쉽습니다. 우리가 해야 할 일은 콜백을 평면화하는 것입니다. Promise 객체에는 다음과 같은 기능이 있습니다.
step1().then(function(value1){ return step2(value1); }).then(function(value2){ return step3(value2); }).then(function(){ //some code })
중첩이 줄어든 것을 볼 수 있지만 비동기 작업을 Like 동기로 변경할 수 있다면 이것이 가장 이상적인 솔루션은 아닙니다. 중첩이 없더라도 프로그램을 이해하기가 더 쉬워집니다. Generator 기능은 우리에게 그러한 기회를 제공합니다.
function *workflow(){ var value1 = yield step1(); var value2 = yield step2(); var value3 = yield step3(); //some code }
이것이 우리가 원하는 결과입니다. 비동기 프로그래밍은 동기 프로그래밍의 한 형태입니다. 다음에 해야 할 일은 이 생성기를 실행시키는 것이므로 실행자가 필요합니다. co는 실행자이므로 Generator가 자동으로 실행될 수 있습니다.
co(function *workflow(){ var value1 = yield step1(); var value2 = yield step2(); var value3 = yield step3(); //some code });
co에는 제한 사항이 있습니다. Promise 객체나 Thunk 함수만 뒤에 올 수 있습니다. co에 대한 자세한 소개는 Ruan 선생님의 글의 의미와 사용법을 참조하세요. co 함수 라이브러리. 그러나 이 방법은 여전히 외부 라이브러리 기능에 의존해야 하므로 ES6에서는 async 및 wait 키워드가 제안되었습니다. async 및 wait는 실제로 Generator의 구문 설탕입니다. 자체 액추에이터가 함께 제공됩니다. 위 코드를 비동기 형식으로 다시 작성합니다.
async function workflow(){ var value1 = await step1(); var value2 = await step2(); var value3 = await step3(); //some code } var result = workflow();
async没有了co的限制。await关键字后面可以跟 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。