async/awaitを理解する
4865 ワード
ES 7が提案したは、アクチュエータを内蔵する.Generator関数の実行は、アクチュエータに依存する必要があります. より良い意味. である.より広い適用性. とすることができる.の戻り値はPromiseです. を呼び出すことができる.
Asyncと他の非同期操作の対比
まず、Fetch方法を定義し、github userの情報を取得する.
構文
async関数はPromiseオブジェクトに戻ります.
すなわち、
Async関数のエラー処理
プロジェクトでどのように使うか?
相変わらず
Frther Reading Understanding JavaScript’s async await Aync/Await-Best Practices in Aynchronous Programming 非同期動作とAsync関数 最初の文章は私のブログです.chenhuichao.com
async
関数は、JavaScriptが非同期動作に対して最終的な解決策を持つようになりました.No more calback hell.async
関数は、Generator
関数のシンタックス飴です.キーワードasync
を用いて表され、非同期は関数内部でawait
を使用して表される.Generatorに比べて、Async
関数の改善は以下の4点にある.Aysnc
は、関数自体がアクチュエータを備えています.呼び出しは、通常の関数の呼び出しと同じです.async
およびawait
は、*
およびyield
に比べてより語義化されたco
モジュールは、yield
コマンドの後はThunk関数またはPromiseオブジェクトのみとすることを約束しています.async
関数のawait
コマンドの後は、Promiseまたは元のタイプの値(Number、string、bootlean)async
関数戻り値はPromiseオブジェクトであり、Generator関数が返したIteratorオブジェクトよりも便利であり、then()
方法を直接使用してAsyncと他の非同期操作の対比
まず、Fetch方法を定義し、github userの情報を取得する.
function fetchUser() {
return new Promise((resolve, reject) => {
fetch('https://api.github.com/users/superman66')
.then((data) => {
resolve(data.json());
}, (error) => {
reject(error);
})
});
}
Promise方式/**
* Promise
*/
function getUserByPromise() {
fetchUser()
.then((data) => {
console.log(data);
}, (error) => {
console.log(error);
})
}
getUserByPromise();
Promiseの方式はcalback hellを解決しましたが、この方式はPromiseのthen()
方法に満ちています.処理の流れが複雑であれば、全セグメントのコードはthen
に満ちています.語義化が明確ではなく、コードフローは実行フローをよく表していません.Generator方式/**
* Generator
*/
function* fetchUserByGenerator() {
const user = yield fetchUser();
return user;
}
const g = fetchUserByGenerator();
const result = g.next().value;
result.then((v) => {
console.log(v);
}, (error) => {
console.log(error);
})
Generatorの方式はPromiseのいくつか問題を解決して、流れは更に直観的で、語義化します.しかし、Generatorの問題は、関数の実行は、毎回g.next()
によって実行される必要があることである.async方式/**
* async
*/
async function getUserByAsync(){
let user = await fetchUser();
return user;
}
getUserByAsync()
.then(v => console.log(v));
async
関数は、上記の2つの方法の問題を完璧に解決した.流れがはっきりしていて、直観的で、意味がはっきりしています.非同期プロセスは操作同期フローのようです.同時にasync
関数は、実行時に手動でロードする必要がありません.構文
async関数はPromiseオブジェクトに戻ります.
async
関数内部returnの戻り値.then
方法のコールバック関数のパラメータになります.async function f() {
return 'hello world'
};
f().then( (v) => console.log(v)) // hello world
async
関数の内部に異常があると、戻ってきたPromiseオブジェクトの状態がreject
状態になります.投げられたエラーは、catch
方法のコールバック関数によって受信される.async function e(){
throw new Error('error');
}
e().then(v => console.log(v))
.catch( e => console.log(e));
async関数が戻ってきたPromiseオブジェクトは、内部のawaitコマンドのPromiseオブジェクトが実行されるまで、状態が変化します.すなわち、
async
関数内部の非同期動作が全部実行された場合にのみ、then
方法のコールバックが実行される.const delay = timeout => new Promise(resolve=> setTimeout(resolve, timeout));
async function f(){
await delay(1000);
await delay(2000);
await delay(3000);
return 'done';
}
f().then(v => console.log(v)); // 6s 'done'
通常、await命令の後に続くのはPromiseです.そうでないと、即戦力に変換されるPromiseも次のようになります.async function f() {
return await 1
};
f().then( (v) => console.log(v)) // 1
リターンがrejectの状態である場合、catch
方法によって捕捉される.Async関数のエラー処理
async
関数の文法は難しくないです.エラー処理では難しいです.まず次の例を見てみます.let a;
async function f() {
await Promise.reject('error');
a = await 1; // await
}
f().then(v => console.log(a));
上記のように、async
関数のうちの1つがawait
でreject状態が発生している限り、後のawait
は実行されない.解決策:try/catch
を追加することができます.//
let a;
async function correct() {
try {
await Promise.reject('error')
} catch (error) {
console.log(error);
}
a = await 1;
return a;
}
correct().then(v => console.log(a)); // 1
await
が複数あるなら、それを全部try/catch
に置くことができる.プロジェクトでどのように使うか?
相変わらず
babel
によって使用されている.presets
をstage-3
に設定するだけでいいです.インストール依存:npm install babel-preset-es2015 babel-preset-stage-3 babel-runtime babel-plugin-transform-runtime
修正.babelrc
:"presets": ["es2015", "stage-3"],
"plugins": ["transform-runtime"]
これにより、プロジェクトにasync
関数を使用することができます.Frther Reading