Rumah > Artikel > hujung hadapan web > Menyelam mendalam ke dalam fungsi async dalam JavaScript
Nilai pulangan fungsi async ialah objek janji, dan hasil objek janji ditentukan oleh pulangan nilai pelaksanaan fungsi async. Fungsi async boleh menjadikan operasi tak segerak lebih mudah, ia adalah gula sintaksis Generator.
mentakrifkan fungsi async Cirinya ialah walaupun hasil pulangan dalaman bagi fungsi bukan objek janji , hasil pulangan terakhir untuk memanggil fungsi. masih merupakan objek janji , kodnya adalah seperti berikut:
Jika hasil yang dikembalikan bukan objek Promise:
<script> async function fn(){ // 返回的结果是字符串 // return '123' // // 返回的结果是undefined // return; // 返回的结果是抛出一个异常 throw new 'error' } const result = fn() console.log(result); </script>
Jika hasil yang dikembalikan ialah Apabila menggunakan objek Promise, kita boleh menggunakan kaedah kemudian seperti biasa, seperti berikut:
<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>
Melalui pengenalan async di atas, saya merasakan bahawa fungsinya agak Hambar, sebenarnya tidak, tetapi async perlu digunakan dengan menunggu untuk mencapai kesan gula sintaksis.
Ciri-ciri menunggu:
menunggu mesti ditulis dalam fungsi async
Ungkapan di sebelah kanan sisi menunggu Secara amnya, objek janji
menunggu mengembalikan nilai janji yang berjaya
Jika janji menunggu gagal, pengecualian akan dilemparkan dan perlu ditangkap dan diproses melalui percubaan. ..catch
Secara terang-terangan: await adalah bersamaan dengan fungsi panggil balik pertama kaedah kemudian, hanya mengembalikan nilai yang berjaya dan nilai yang gagal perlu ditangkap dengan mencuba...tangkap.
Ralat dilemparkan ke dalam fungsi async, yang akan menyebabkan objek Promise yang dikembalikan menjadi ditolak. Objek ralat yang dilemparkan akan diterima oleh fungsi panggil balik kaedah tangkapan.
<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>
Ringkasan :
(1) Di sebalik penantian perintah Promise object, hasil larian mungkin ditolak, jadi sebaiknya letakkan perintah await dalam try...catch code block.
(2)Jika terdapat operasi tak segerak di sebalik berbilang perintah menunggu, jika tiada perhubungan seterusnya, sebaiknya biarkan ia tercetus pada masa yang sama.
Contohnya: tunggu Promise.all([a(), b()]), berikut adalah sebutan ringkas
(3)menunggu Perintah hanya boleh digunakan dalam fungsi async Jika digunakan dalam fungsi biasa, ralat akan dilaporkan.
(4)(Fahami prinsip pengendalian async) fungsi async boleh mengekalkan timbunan berjalan, apabila menjalankan tugas tak segerak di dalam fungsi normal , jika tugas tak segerak tamat, fungsi biasa mungkin telah lama dijalankan, dan konteks tugas tak segerak telah hilang Jika tugas tak segerak melaporkan ralat, timbunan ralat tidak akan termasuk fungsi biasa; tugas di dalam fungsi async sedang berjalan, fungsi async dijeda dilaksanakan, jadi sebaik sahaja tugas asynchronous dalam fungsi async berjalan dan ralat dilaporkan, timbunan ralat akan termasuk fungsi 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 () => {};
dan bacaan janji dijelaskan sebelum Kandungan daripada fail adalah sama. Kami juga boleh menggunakan async untuk membaca fail tersebut adalah seperti berikut:
// 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()
janji menghantar permintaan ajax, kami juga boleh menggunakan async untuk menghantar permintaan ajax adalah seperti berikut:
<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>
<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>Prinsip pelaksanaan fungsi async adalah untuk membalut fungsi Penjana dan pelaksana automatik dalam fungsi.
<script> async function fn(args) {} // 等同于 function fn(args) { // spawn函数就是自动执行器 return spawn(function* () {}); } </script>Kami boleh menganalisis ciri penulisan dan gaya Penjana dan kod async:
<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高级教程】
Atas ialah kandungan terperinci Menyelam mendalam ke dalam fungsi async dalam JavaScript. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!