ホームページ > 記事 > ウェブフロントエンド > JavaScript の非同期関数の詳細
async 関数の戻り値は Promise オブジェクトであり、Promise オブジェクトの結果は戻り値によって決まります。非同期関数実行の値。 async 関数は非同期操作をより便利にするもので、一言で言えばジェネレーターの糖衣構文です。
非同期関数を定義します。その特徴は、 関数の内部戻り結果が Promise オブジェクトではない場合でも、関数呼び出しの最終的な戻り結果が次のとおりであることです。まだ Promise オブジェクト である場合、コードは次のとおりです: 返された結果が Promise オブジェクトではない場合: <script>
async function fn(){
// 返回的结果是字符串
// return '123'
// // 返回的结果是undefined
// return;
// 返回的结果是抛出一个异常
throw new 'error'
}
const result = fn()
console.log(result);
</script>
<script> async function fn(){ return new Promise((resolve,reject)=>{ // resolve('成功的数据') reject('失败的数据') }) } const result = fn() // 调用 then 方法 result.then((value)=>{ console.log(value); },(reason)=>{ console.log(reason); // 打印失败的数据 }) </script>await 式
: await は非同期関数内に記述する必要があります 右側の式await の側 一般に、これは Promise オブジェクトです。
await は、成功した Promise の値を返します。
await の Promise が失敗した場合、例外がスローされるため、try を通じてキャプチャして処理する必要があります。 ...catch
率直に言うと、await は then メソッドの最初のコールバック関数と同等であり、成功した値のみを返し、失敗した場合は返されます。値は try...catch で取得する必要があります。
非同期関数内でエラーがスローされ、返された Promise オブジェクトが拒否されます。スローされたエラー オブジェクトは、catch メソッドのコールバック関数によって受信されます。 <script>
const p = new Promise((resolve,reject)=>{
// resolve('用户数据')
reject('用户加载数据失败了')
})
async function fn(){
// 为防止promise是失败的状态,加上try...catch进行异常捕获
try {
// await 返回的结果就是 promise 返回成功的值
let result = await p
console.log(result);
} catch (error) {
console.log(error);//因为是失败的状态,所以打印:用户加载数据失败了
}
}
fn()
</script>
async はファイルを読み取ります(1)await コマンドの背後にある約束オブジェクトの場合、操作結果が拒否される可能性があるため、try...catch コード ブロックに await コマンドを入れるのが最善です。
(2)複数の await コマンドの背後に非同期操作があり、後続の関係がない場合は、それらを同時にトリガーさせるのが最善です。 。
例: await Promise.all([a(), b()])、ここで簡単に説明します (3)
await このコマンドは非同期関数でのみ使用でき、通常の関数で使用するとエラーが報告されます。
(4)(
asyncの動作原理を理解する) async関数は実行中のスタックを保持することができます。通常の関数内で、非同期タスクが終了した場合、通常の関数はずっと前に実行を終了している可能性があり、非同期タスクのコンテキストは消えています。非同期タスクがエラーを報告した場合、エラー スタックには通常の関数は含まれません。 async 関数内の非同期タスクが実行中である場合、async 関数は実行を一時停止しているため、async 関数内の非同期タスクが実行されてエラーが報告されると、エラー スタックには async 関数が含まれます。 async は形式を使用します
// 函数声明 async function foo() {} // 函数表达式 const foo = async function () {}; // 对象的方法 let obj = { async foo() {} }; obj.foo().then(...) // Class 的方法 class Storage { constructor() { this.cachePromise = caches.open('avatars'); } async getAvatar(name) { const cache = await this.cachePromise; return cache.match(`/avatars/${name}.jpg`); } } const storage = new Storage(); storage.getAvatar('jake').then(…); // 箭头函数 const foo = async () => {};
// 1.引入 fs 模块 const fs = require('fs') // 2.读取文件 function index(){ return new Promise((resolve,reject)=>{ fs.readFile('./index.md',(err,data)=>{ // 如果失败 if(err) reject(err) // 如果成功 resolve(data) }) }) } function index1(){ return new Promise((resolve,reject)=>{ fs.readFile('./index1.md',(err,data)=>{ // 如果失败 if(err) reject(err) // 如果成功 resolve(data) }) }) } function index2(){ return new Promise((resolve,reject)=>{ fs.readFile('./index2.md',(err,data)=>{ // 如果失败 if(err) reject(err) // 如果成功 resolve(data) }) }) } // 3.声明一个 async 函数 async function fn(){ let i = await index() let i1 = await index1() let i2 = await index2() console.log(i.toString()); console.log(i1.toString()); console.log(i2.toString()); } fn()
async sends AJAX request
Explain 前
promise ajax リクエストの送信<script> // 发送 AJAX请求,返回的结果是 Promise 对象 function sendAjax(url){ return new Promise((resolve,reject)=>{ // 创建对象 const x = new XMLHttpRequest() // 初始化 x.open('GET',url) // 发送 x.send() // 事件绑定 x.onreadystatechange = function(){ if(x.readyState === 4){ if(x.status >= 200 && x.status < 300){ // 如果响应成功 resolve(x.response) // 如果响应失败 reject(x.status) } } } }) } // promise then 方法测试 // const result = sendAjax("https://ai.baidu.com/").then(value=>{ // console.log(value); // },reason=>{}) // async 与 await 测试 async function fn(){ // 发送 AJAX 请求 let result = await sendAjax("https://ai.baidu.com/") console.log(result); } fn() </script>
と比較して、async と await の関係が Generator と yield の関係に非常に似ていることがわかりました。Generator に詳しくない友人は、私の以前の記事を読んでください:
Generator 説明<script> // Generator 函数 function * person() { console.log('hello world'); yield '第一分隔线' console.log('hello world 1'); yield '第二分隔线' console.log('hello world 2'); yield '第三分隔线' } let iterator = person() // console.log(iterator); 打印的就是一个迭代器对象,里面有一个 next() 方法,我们借助next方法让它运行 iterator.next() iterator.next() iterator.next() // async函数 const person1 = async function (){ console.log('hello world'); await '第一分隔线' console.log('hello world 1'); await '第二分隔线' console.log('hello world 2'); await '第三分隔线' } person1() </script>
async 関数の実装原則は、ジェネレーター関数と自動エグゼキューターを関数内にラップすることです。
<script> async function fn(args) {} // 等同于 function fn(args) { // spawn函数就是自动执行器 return spawn(function* () {}); } </script>ジェネレーターと非同期コードの記述特性とスタイルを分析できます:
<script> // Generator 函数 function Generator(a, b) { return spawn(function*() { let r = null; try { for(let k of b) { r = yield k(a); } } catch(e) { /* 忽略错误,继续执行 */ } return r; }); } // async 函数 async function async(a, b) { let r = null; try { for(let k of b) { r = await k(a); } } catch(e) { /* 忽略错误,继续执行 */ } return r; } </script>
所以 async 函数的实现符合语义也很简洁,不用写Generator的自动执行器,改在语言底层提供,因此代码量少。
从上文代码我们可以总结以下几点:
(1)Generator函数执行需要借助执行器,而async函数自带执行器,即async不需要像生成器一样需要借助 next 方法才能执行,而是会自动执行。
(2)相比于生成器函数,我们可以看到 async 函数的语义更加清晰
(3)上面就说了,async函数可以接受Promise或者其他原始类型,而生成器函数yield命令后面只能是Promise对象或者Thunk函数。
(4)async函数返回值只能是Promise对象,而生成器函数返回值是 Iterator 对象
【推荐学习:javascript高级教程】
以上がJavaScript の非同期関数の詳細の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。