Menyelam mendalam ke dalam fungsi async dalam JavaScript

青灯夜游
Lepaskan: 2022-11-03 20:39:29
ke hadapan
1502 orang telah melayarinya

Menyelam mendalam ke dalam fungsi async dalam JavaScript

fungsi async

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 &#39;123&#39;
        // // 返回的结果是undefined
        // return;
        // 返回的结果是抛出一个异常
        throw new &#39;error&#39;
    }
    const result = fn()
    console.log(result);
</script>
Salin selepas log masuk

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(&#39;成功的数据&#39;)
            reject(&#39;失败的数据&#39;)
        })
    }
    const result = fn()
    // 调用 then 方法
    result.then((value)=>{
        console.log(value);
    },(reason)=>{
        console.log(reason); // 打印失败的数据
    })
</script>
Salin selepas log masuk

menunggu ungkapan

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(&#39;用户数据&#39;)
        reject(&#39;用户加载数据失败了&#39;)
    })
    async function fn(){
        // 为防止promise是失败的状态,加上try...catch进行异常捕获
        try {
            // await 返回的结果就是 promise 返回成功的值
            let result = await p
            console.log(result);
        } catch (error) {
            console.log(error);//因为是失败的状态,所以打印:用户加载数据失败了
        }
    }
    fn()
</script>
Salin selepas log masuk

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.

borang penggunaan async

// 函数声明
async function foo() {}
 
// 函数表达式
const foo = async function () {};
 
// 对象的方法
let obj = { async foo() {} };
obj.foo().then(...)
 
// Class 的方法
class Storage {
  constructor() {
    this.cachePromise = caches.open(&#39;avatars&#39;);
  }
 
  async getAvatar(name) {
    const cache = await this.cachePromise;
    return cache.match(`/avatars/${name}.jpg`);
  }
}
 
const storage = new Storage();
storage.getAvatar(&#39;jake&#39;).then(…);
 
// 箭头函数
const foo = async () => {};
Salin selepas log masuk

fail bacaan 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(&#39;fs&#39;)
 
// 2.读取文件
function index(){
    return new Promise((resolve,reject)=>{
        fs.readFile(&#39;./index.md&#39;,(err,data)=>{
            // 如果失败
            if(err) reject(err)
            // 如果成功
            resolve(data)
        })
    })
}
function index1(){
    return new Promise((resolve,reject)=>{
        fs.readFile(&#39;./index1.md&#39;,(err,data)=>{
            // 如果失败
            if(err) reject(err)
            // 如果成功
            resolve(data)
        })
    })
}
function index2(){
    return new Promise((resolve,reject)=>{
        fs.readFile(&#39;./index2.md&#39;,(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()
Salin selepas log masuk

async menghantar permintaan AJAX<. 🎜>

Sama seperti penjelasan sebelumnya tentang

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(&#39;GET&#39;,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>
Salin selepas log masuk

Berbanding dengan Generator

Kami mendapati bahawa hubungan antara async dan await sangat serupa dengan hubungan antara Generator dan yield Generator boleh membaca artikel saya sebelum ini :

Penjelasan penjana ; Selepas perbandingan, kami mendapati: Fungsi async adalah untuk menggantikan asterisk (*) fungsi Generator dengan async, dan menggantikan hasil dengan await. Perbandingan kod adalah seperti berikut:

<script>
    // Generator 函数
    function * person() {
        console.log(&#39;hello world&#39;);
        yield &#39;第一分隔线&#39; 
    
        console.log(&#39;hello world 1&#39;);
        yield &#39;第二分隔线&#39;
    
        console.log(&#39;hello world 2&#39;);
        yield &#39;第三分隔线&#39;
    }
    let iterator = person()
    // console.log(iterator); 打印的就是一个迭代器对象,里面有一个 next() 方法,我们借助next方法让它运行
    iterator.next()
    iterator.next()
    iterator.next()
 
    // async函数
    const person1 = async function (){
        console.log(&#39;hello world&#39;);
        await &#39;第一分隔线&#39; 
    
        console.log(&#39;hello world 1&#39;);
        await &#39;第二分隔线&#39;
    
        console.log(&#39;hello world 2&#39;);
        await &#39;第三分隔线&#39;
    }
    person1()
</script>
Salin selepas log masuk

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>
Salin selepas log masuk
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>
Salin selepas log masuk

所以 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!

Label berkaitan:
sumber:csdn.net
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!