async wait動作原理
asyncとawaitはどのように操作しますか?
babelの試用版で変換を行い、内部の動作を理解します.
非同期関数を使用せずに、次のコードを使用してテストする準備をします.
async、waitは非同期関数だけを使用しますか?考えてみればそうではない.任意の関数にawaitを適用できます.
まず、次のコードの結果値を推定します.
内部の原理が気になる人を見ればいいです.
上のコードをバーベルに変換すると、
上のコードをバーベルから回すと、次のコードが表示されます.
惨めで見るに忍びない
私たちにとって、処理ミスの部分は見えません.コードをより簡単に変更してから確認しましょう.
かつてasyncだったb関数はbとbに分けられ,待機していた部分はjenerator関数となり,内部から完成品に変わったことがわかる.これしかないか確認してから、コードを下に見てみましょう.
_asyncToGenerator関数はasyncToGeneratorと呼ばれ、generator関数に変更されたasync関数をgeneratorオブジェクトに変更して実行する関数です.パラメータとしてgenerator関数を受け入れます. Promiseオブジェクトの関数を返します. どのPromiseオブジェクトを返しますか?パラメータで受信したジェネレータ関数を使用してジェネレータオブジェクトを作成します.(gen) next関数を実行します.==asyncGeneratorStep関数を実行します. 最終的に、asyncToGenerator関数は、パラメータとして受信されたGenerator関数をnextとすることができる.つまり,1回目の待ちを実行すればよい.
next関数asyncGeneratorStepについて説明します.
asyncGeneratorStep
人の字から一つ一つ調べましょう. gen:JENNERオブジェクト 解析:承諾された解析関数 next:asyncToGeneratorのnext関数(再帰的に使用可能). キー、arg:arg:1つのキーとパラメータ値arg(例ではthrowがないと仮定)、jeneratorのnextまたはthrow(throwがないと仮定)を実行するために使用されます.
の最初のasyncToGeneratorで実行されるasyncGeneratorStepでは、genValueがgen(サードパーティオブジェクト)のnextメソッドを呼び出します.(最初の待機が実行されます.) 今genValueは終わりましたかgenValuedoneと確認して完了した場合、解析が完了していない場合は、後続のタスクをthereに渡して実行します.(つまり、最初の待機後のタスクが入って実行されます.) ビット目の操作を繰り返します.
async,awaiの原理はここに隠されている.
async関数はサードパーティ関数に変更されて実行されます.
async関数で変更したjner layer関数が内部で生成されると、後の作業がthenに渡されます.
これは、後の操作がマイクロタスクキューに入り、呼び出しスタックが空になり、実行されるため、上部の例と同様の現象が発生するためです.
結論! async,await関数 サードパーティ関数の実行時に、生産量を基準として、承諾から方法に移行します. このとき、アクセスメソッドの後部はマイクロタスクキューに入り、コールスタックが空になった後、実行を継続する. の最後の部分
asyncToGenerator、asyncGeneratorStep関数の原理を理解し、babelでtransformileコードを初めて見るとわかります.
結局、待っていた秘密はジェナレットとプロミスだった.
この現象は反応の中でも予想外の結果を生むので、次のヒントで理解してみましょう.
ref https://meetup.toast.com/posts/73 https://medium.com/sjk5766/async-await-原理-cc 643 f 18526 d https://ko.javascript.info/microtask-queue
babelの試用版で変換を行い、内部の動作を理解します.
非同期関数を使用せずに、次のコードを使用してテストする準備をします.
async、waitは非同期関数だけを使用しますか?考えてみればそうではない.任意の関数にawaitを適用できます.
まず、次のコードの結果値を推定します.
function a() {console.log('a')}
async function b() {
console.log('b1')
await a()
console.log('b2')
}
b()
console.log('c')
実際、上記の結果値を予測できれば、次の文章を見る必要はありません.内部の原理が気になる人を見ればいいです.
上のコードをバーベルに変換すると、
上のコードをバーベルから回すと、次のコードが表示されます.
惨めで見るに忍びない
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _asyncToGenerator(fn) {
return function () {
var self = this,
args = arguments;
return new Promise(function (resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'next', value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'throw', err);
}
_next(undefined);
});
};
}
function a() {
console.log('a');
}
function b() {
return _b.apply(this, arguments);
}
function _b() {
_b = _asyncToGenerator(function* () {
console.log('b1');
yield a();
console.log('b2');
});
return _b.apply(this, arguments);
}
b();
console.log('c');
もっと簡単に私たちにとって、処理ミスの部分は見えません.コードをより簡単に変更してから確認しましょう.
かつてasyncだったb関数はbとbに分けられ,待機していた部分はjenerator関数となり,内部から完成品に変わったことがわかる.これしかないか確認してから、コードを下に見てみましょう.
function asyncGeneratorStep(gen, resolve, _next, key, arg) {
/**
* 제네레이터 객체의 next 메소드를 호출한다.
*/
const genValue = gen[key](arg);
/**
* generator가 done이 됐으면 resolve한다.
* 아니면 뒤의 작업은 then으로 이어서 한다. => 여기서 마이크로 테스크 큐로 들어가기 때문에 순서의 차이가 발생한다.
*/
if (genValue.done) {
resolve(genValue.value);
} else {
Promise.resolve(genValue.value).then(_next);
}
}
function _asyncToGenerator(fn) {
return function () {
const self = this;
const args = arguments;
return new Promise((resolve) => {
// gen: 제네레이터 객체
const gen = fn.apply(self, args);
const _next = (value) => {
asyncGeneratorStep(gen, resolve, _next, 'next', value);
};
// 첫번째 await까지 실행한다.
_next(undefined);
});
};
}
function a() {
console.log('a');
}
function b() {
return _b.apply(this, arguments);
}
function _b() {
function* asyncFunction() {
console.log('b1');
yield a();
console.log('b2');
}
_b = _asyncToGenerator(asyncFunction);
return _b.apply(this, arguments);
}
b();
console.log('c');
コードの理解_asyncToGenerator
およびasyncGeneratorStep
は、上記のコードから理解される._asyncToGenerator
の内部ではasyncGeneratorStep
が使用される._asyncToGenerator
function _asyncToGenerator(fn) {
return function () {
const self = this;
const args = arguments;
return new Promise((resolve) => {
const gen = fn.apply(self, args);
const _next = (value) => {
asyncGeneratorStep(gen, resolve, _next, 'next', value);
};
_next(undefined);
});
};
}
new Promise((resolve) => {
// gen: 제네레이터 객체
const gen = fn.apply(self, args);
const _next = (value) => {
asyncGeneratorStep(gen, resolve, _next, 'next', value);
};
// 첫번째 yield(await)까지 실행한다.
_next(undefined);
});
next関数asyncGeneratorStepについて説明します.
asyncGeneratorStep
人の字から一つ一つ調べましょう.
function asyncGeneratorStep(gen, resolve, _next, key, arg) {
/**
* 제네레이터 객체의 next 메소드를 호출한다.
*/
const genValue = gen[key](arg);
/**
* generator가 done이 됐으면 resolve한다.
* 아니면 뒤의 작업은 then으로 이어서 한다. => 여기서 마이크로 테스크 큐로 들어가기 때문에 순서의 차이가 발생한다.
*/
if (genValue.done) {
resolve(genValue.value);
} else {
Promise.resolve(genValue.value).then(_next);
}
}
asysn wait原理async,awaiの原理はここに隠されている.
async関数はサードパーティ関数に変更されて実行されます.
async関数で変更したjner layer関数が内部で生成されると、後の作業がthenに渡されます.
これは、後の操作がマイクロタスクキューに入り、呼び出しスタックが空になり、実行されるため、上部の例と同様の現象が発生するためです.
結論!
asyncToGenerator、asyncGeneratorStep関数の原理を理解し、babelでtransformileコードを初めて見るとわかります.
結局、待っていた秘密はジェナレットとプロミスだった.
この現象は反応の中でも予想外の結果を生むので、次のヒントで理解してみましょう.
ref
Reference
この問題について(async wait動作原理), 我々は、より多くの情報をここで見つけました https://velog.io/@proshy/async-await-동작원리テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol