ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScript の非同期エクスペリエンスのためのより優れたソリューションを共有する
この記事では主に JavaScript エクスペリエンスの非同期性に関するより良い解決策について説明します。この側面を必要とする友人は参考にしてください。
1. 非同期ソリューションの進化の歴史
JavaScript の非同期操作は常に厄介な問題であるため、人々はそれに対するさまざまな解決策を提案し続けています。これは、最も初期のコールバック関数 (ajax の古い友人)、Promise (新しい友人ではない)、そして ES6 Generator (強力な友人) にまで遡ることができます。
数年前には有名な Async.js を使っていたかもしれませんが、コールバック関数は廃止されておらず、エラー処理も「コールバック関数の最初のパラメーターはエラーを渡すために使用される」という規則に従っていました。よく知られたコールバック地獄は、Generator がこの非同期スタイルを変更するまで、依然として顕著な問題でした。
しかし、ES7 の async await (Bunker の新しい友達) の登場により、非同期機構を持ちながら簡単に同期スタイルのコードを書くことができるようになり、現時点で最もシンプルでエレガントで最良のソリューションであると言えます。
2. async await 構文
async await 構文は比較的単純で、ジェネレーターの糖衣構文と考えることができます。アスタリスクや yield よりもセマンティックです。以下は、1 秒後に hello world を出力する簡単な例です。
function timeout(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } async function asyncPrint(value, ms) { await timeout(ms); console.log(value) } asyncPrint('hello world', 1000);await は、非同期関数でのみ使用できます。通常の関数で使用すると、
function timeout(ms) { return new Promise((resolve) => { setTimeout(_ => {resolve('hello world')}, ms); }); } async function asyncPrint(ms) { let result = await timeout(ms); console.log(result) } asyncPrint(1000);3. async await エラー処理
function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(_ => {reject('error')}, ms);//reject模拟出错,返回error }); } async function asyncPrint(ms) { try { console.log('start'); await timeout(ms);//这里返回了错误 console.log('end');//所以这句代码不会被执行了 } catch(err) { console.log(err); //这里捕捉到错误error } } asyncPrint(1000);複数の await がある場合は、try catch にまとめることができます。
async function main() { try { const async1 = await firstAsync(); const async2 = await secondAsync(); const async3 = await thirdAsync(); } catch (err) { console.error(err); } }4. async await に関する注意事項
const async1 = await firstAsync(); const async2 = await secondAsync();上記のコードで、async1 と async2 が 2 つの独立した非同期操作である場合、firstAsync が完了するまで SecondAsync が実行されないため、このように記述するとさらに時間がかかります。 Promise.all:
let [async1, async2] = await Promise.all([firstAsync(), secondAsync()]);3)。await は非同期関数でのみ使用できます。通常の関数で使用すると、エラーが報告されます:
async function main() { let docs = [{}, {}, {}]; //报错 await is only valid in async function docs.forEach(function (doc) { await post(doc); console.log('main'); }); } function post(){ return new Promise((resolve) => { setTimeout(resolve, 1000); }); }async を forEach 内部メソッドに追加するだけです。
async function main() { let docs = [{}, {}, {}]; docs.forEach(async function (doc) { await post(doc); console.log('main'); }); } function post(){ return new Promise((resolve) => { setTimeout(resolve, 1000); }); }
しかし、3 つのメインが同時に出力されることがわかります。これは、ポストが順番ではなく同時に実行されることを意味し、3 つのメインが 1 秒間隔で出力されるという問題を解決できます。
async function main() { let docs = [{}, {}, {}]; for (let doc of docs) { await post(doc); console.log('main'); } } function post(){ return new Promise((resolve) => { setTimeout(resolve, 1000); }); }つまり、async await を使用した後は、非常に簡潔でエレガントなコードを使用してさまざまな派手な非同期操作を実装できるようになり、ビジネス ロジックが複雑な場合でもコールバック地獄に陥る必要がなくなりました。これが究極の解決策であるとはあえて言いませんが、確かに現時点で最もエレガントな解決策です。 関連する推奨事項:
以上がJavaScript の非同期エクスペリエンスのためのより優れたソリューションを共有するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。