생성기를 사용한 비동기 / 대기 및 ES6 수율의 차이점
저는이 환상적인 기사를 읽고있었습니다.
https://www.promisejs.org/generators/
제너레이터 함수를 처리하기위한 도우미 함수 인이 함수를 명확하게 강조합니다.
function async(makeGenerator){
return function () {
var generator = makeGenerator.apply(this, arguments);
function handle(result){
// result => { done: [Boolean], value: [Object] }
if (result.done) return Promise.resolve(result.value);
return Promise.resolve(result.value).then(function (res){
return handle(generator.next(res));
}, function (err){
return handle(generator.throw(err));
});
}
try {
return handle(generator.next());
} catch (ex) {
return Promise.reject(ex);
}
}
}
나는 async 키워드가 구현되는 방식과 다소 비슷하다고 가정합니다 async/await
. 그렇다면 문제는 await
키워드와 키워드 의 차이점이 도대체 무엇 yield
일까요? 않는 await
반면 항상 약속에 뭔가를 돌려 yield
그러한 보증을하지 않습니다? 그것은 내 최선의 추측입니다!
또한 'spawn'함수를 설명하는이 기사에서 async / await가 생성기를 사용한 yield와 어떻게 유사한 지 확인할 수 있습니다. https://jakearchibald.com/2014/es7-async-functions/
yield
의 빌딩 블록으로 간주 될 수 있습니다 await
. yield
주어진 값을 받아 호출자에게 전달합니다. 그런 다음 호출자는 해당 값 (1)으로 원하는 모든 작업을 수행 할 수 있습니다. 나중에 호출자는 (2) 표현식 generator.next()
의 결과가되는 생성자 (를 통해 )에 값을 다시 제공 yield
하거나 yield
(3) 표현식에 의해 throw되는 것처럼 보이는 오류를 제공 할 수 있습니다 .
async
- await
를 사용하는 것으로 간주 할 수 있습니다 yield
. (즉, (1) 호출자에 async
- await
드라이버 - 당신이 게시 된 기능과 유사)와 유사한 알고리즘을 사용하여 약속의 값을 바꿈됩니다 new Promise(r => r(value)
(참고, 하지 Promise.resolve
,하지만 그건 큰 문제가 아니다). 그런 다음 약속이 해결 될 때까지 기다립니다. 충족되면 충족 된 값을 (2)로 다시 전달합니다. 거부하면 (3)에서 오류로 거부 사유를 던집니다.
따라서 async
- 의 유용성은 산출 된 값을 약속으로 풀고 해결 된 값을 다시 전달하여 함수가 최종 값을 반환 할 때까지 반복 await
하는 데 사용 yield
하는 이 기계입니다 .
음, async / await와 생성기 사이에는 매우 밀접한 관계가 있다는 것이 밝혀졌습니다. 그리고 async / await는 항상 제너레이터에 구축 될 것이라고 믿습니다. Babel이 async / await를 변환하는 방식을 살펴보면 :
Babel은 다음을 수행합니다.
this.it('is a test', async function () {
const foo = await 3;
const bar = await new Promise(resolve => resolve('7'));
const baz = bar * foo;
console.log(baz);
});
그리고 이것을 이렇게
function _asyncToGenerator(fn) {
return function () {
var gen = fn.apply(this, arguments);
return new Promise(function (resolve, reject) {
function step(key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
return Promise.resolve(value).then(function (value) {
return step("next", value);
}, function (err) {
return step("throw", err);
});
}
}
return step("next");
});
};
}
this.it('is a test', _asyncToGenerator(function* () { // << now it's a generator
const foo = yield 3; // <<< now it's yield, not await
const bar = yield new Promise(resolve => resolve(7));
const baz = bar * foo;
console.log(baz);
}));
당신은 수학을합니다.
이것은 async 키워드가 단지 그 래퍼 함수 인 것처럼 보이게하지만, 만약 그렇다면 await가 yield로 바뀌면 나중에 네이티브가 될 때 그림에 약간 더 많은 것이있을 것입니다.
이에 대한 자세한 설명은 https://www.promisejs.org/generators/ 에서 확인할 수 있습니다.
도대체
await
키워드와 키워드 의 차이점은 무엇yield
입니까?
The await
keyword is only to be used in async function
s, while the yield
keyword is only to be used in generator function*
s. And those are obviously different as well - the one returns promises, the other returns generators.
Does
await
always turn something into a promise, whereasyield
makes no such guarantee?
Yes, await
will call Promise.resolve
on the awaited value.
yield
just yields the value outside of the generator.
tldr;
Use Async/Await 99% of the time over Generators. Why?
Async/Await directly replaces the most common work-flow of promise chains allowing code to be declared as if it was synchronous, dramatically simplifying it.
생성기는 서로 의존하고 결국 "완료"상태가되는 일련의 비동기 작업을 호출하는 사용 사례를 추상화합니다. 가장 간단한 예는 결국 마지막 세트를 반환하는 결과를 통해 페이징하는 것이지만 연속적으로 즉시 호출하지 않고 필요한 경우에만 페이지를 호출합니다.
Async / Await는 실제로 Promise 작업을 더 쉽게하기 위해 Generators 위에 구축 된 추상화입니다.
Async / Await vs. Generators에 대한 자세한 설명보기
약속과 함께 대기 / 비동기를 이해하는 데 사용한이 테스트 프로그램을 사용해보십시오.
프로그램 # 1 : 약속없이 순서대로 실행되지 않음
function functionA() {
console.log('functionA called');
setTimeout(function() {
console.log('functionA timeout called');
return 10;
}, 15000);
}
function functionB(valueA) {
console.log('functionB called');
setTimeout(function() {
console.log('functionB timeout called = ' + valueA);
return 20 + valueA;
}, 10000);
}
function functionC(valueA, valueB) {
console.log('functionC called');
setTimeout(function() {
console.log('functionC timeout called = ' + valueA);
return valueA + valueB;
}, 10000);
}
async function executeAsyncTask() {
const valueA = await functionA();
const valueB = await functionB(valueA);
return functionC(valueA, valueB);
}
console.log('program started');
executeAsyncTask().then(function(response) {
console.log('response called = ' + response);
});
console.log('program ended');
프로그램 2 : 약속 있음 :
function functionA() {
return new Promise((resolve, reject) => {
console.log('functionA called');
setTimeout(function() {
console.log('functionA timeout called');
// return 10;
return resolve(10);
}, 15000);
});
}
function functionB(valueA) {
return new Promise((resolve, reject) => {
console.log('functionB called');
setTimeout(function() {
console.log('functionB timeout called = ' + valueA);
return resolve(20 + valueA);
}, 10000);
});
}
function functionC(valueA, valueB) {
return new Promise((resolve, reject) => {
console.log('functionC called');
setTimeout(function() {
console.log('functionC timeout called = ' + valueA);
return resolve(valueA + valueB);
}, 10000);
});
}
async function executeAsyncTask() {
const valueA = await functionA();
const valueB = await functionB(valueA);
return functionC(valueA, valueB);
}
console.log('program started');
executeAsyncTask().then(function(response) {
console.log('response called = ' + response);
});
console.log('program ended');
In many ways, generators are a superset of async/await. Right now async/await has cleaner stack traces than co, the most popular async/await-like generator based lib. You can implement your own flavor of async/await using generators and add new features, like built-in support for yield
on non-promises or building it on RxJS observables.
So, in short, generators give you more flexibility and generator-based libs generally have more features. But async/await is a core part of the language, it's standardized and won't change under you, and you don't need a library to use it. I have a blog post with more details on the difference between async/await and generators.
'developer tip' 카테고리의 다른 글
ASP.NET Core의 토큰 기반 인증 (새로 고침) (0) | 2020.11.15 |
---|---|
Git 정리 란 무엇입니까? (0) | 2020.11.15 |
Typescript : 중첩 된 개체에 대한 인터페이스를 어떻게 정의합니까? (0) | 2020.11.15 |
레이아웃이 iOS 상태 표시 줄과 겹치는 것을 방지하는 방법 (0) | 2020.11.15 |
WiX ICE 유효성 검사 오류 (0) | 2020.11.14 |