Heim  >  Artikel  >  Web-Frontend  >  Ein tiefer Einblick in asynchrone Funktionen in JavaScript

Ein tiefer Einblick in asynchrone Funktionen in JavaScript

青灯夜游
青灯夜游nach vorne
2022-11-03 20:36:441530Durchsuche

Ein tiefer Einblick in asynchrone Funktionen in JavaScript

asynchrone Funktion

Der Rückgabewert der asynchronen Funktion ist das Versprechensobjekt, und das Ergebnis des Versprechensobjekts wird durch den Rückgabewert der Ausführung der asynchronen Funktion bestimmt. Die Async-Funktion kann asynchrone Vorgänge komfortabler machen. Kurz gesagt, sie ist der syntaktische Zucker von Generator.

Definieren Sie eine asynchrone Funktion. Auch wenn das interne Rückgabeergebnis der Funktion kein Versprechensobjekt ist, ist das endgültige Rückgabeergebnis des Funktionsaufrufs dennoch ein Versprechensobjekt folgt: Wenn das zurückgegebene Ergebnis kein Promise-Objekt ist. In diesem Fall:

<script>
    async function fn(){
        // 返回的结果是字符串
        // return &#39;123&#39;
        // // 返回的结果是undefined
        // return;
        // 返回的结果是抛出一个异常
        throw new &#39;error&#39;
    }
    const result = fn()
    console.log(result);
</script>

Wenn das zurückgegebene Ergebnis ein Promise-Objekt ist, können wir die then-Methode normal wie folgt verwenden:

<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>

await expression

Durch die obige Einführung in Async habe ich das Gefühl, dass seine Funktion etwas geschmacklos ist, eigentlich nicht, aber Async muss zusammen mit Wait verwendet werden, um die Wirkung von syntaktischem Zucker zu erzielen.

await-Eigenschaften

:

await muss in der asynchronen Funktion geschrieben werden await Der Ausdruck auf der rechten Seite ist im Allgemeinen ein Versprechensobjekt await gibt den Wert des Versprechenserfolgs zurück

awaits Versprechen ist fehlgeschlagen, An Es wird eine Ausnahme ausgelöst, die durch try...catch erfasst und verarbeitet werden muss für fehlgeschlagene Werte ..catch zum Erfassen.

Ein in der asynchronen Funktion ausgelöster Fehler führt dazu, dass das zurückgegebene Promise-Objekt abgelehnt wird. Das ausgelöste Fehlerobjekt wird von der Rückruffunktion der Catch-Methode empfangen.

<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>

Zusammenfassung

: (1)

Das Promise-Objekt hinter dem Wait-Befehl kann dadurch abgelehnt werden, daher ist es am besten, den Wait-Befehl in den try...catch-Code einzufügen Block.

(2)Wenn sich hinter mehreren Wartebefehlen asynchrone Vorgänge befinden und keine nachfolgende Beziehung besteht, ist es am besten, sie gleichzeitig auslösen zu lassen.

Zum Beispiel: waiting Promise.all([a(), b()]), hier ist eine kurze Erwähnung

(3)

Der Befehlwait kann nur in asynchronen Funktionen verwendet werden, wenn er in normalen Funktionen verwendet wird , Es wird ein Fehler gemeldet.

(4)

(Verstehen Sie das Funktionsprinzip von Async

) Wenn eine asynchrone Aufgabe innerhalb einer normalen Funktion ausgeführt wird, kann dies bei der normalen Funktion der Fall sein Die Ausführung der asynchronen Aufgabe ist schon vor langer Zeit abgeschlossen, und die Kontextumgebung ist verschwunden. Wenn eine asynchrone Aufgabe einen Fehler meldet, enthält der Fehlerstapel keine normalen Funktionen, während die asynchrone Aufgabe in der asynchronen Funktion ausgeführt wird Sobald die asynchrone Aufgabe innerhalb der asynchronen Funktion ausgeführt wird und ein Fehler gemeldet wird, enthält der Fehlerstapel asynchrone Funktionen. Async-Nutzungsform

async sendet AJAX-AnfragenÄhnlich wie bei der vorherigen Erklärung von

Versprechen, Ajax-Anfragen zu senden

können wir auch asynchron verwenden, um Ajax-Anfragen zu senden:

// 函数声明
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 () => {};
Verglichen mit Generator

Wir haben festgestellt, dass die Beziehung zwischen Async und Await der Beziehung zwischen Generator und Yield sehr ähnlich ist. Freunde, die mit Generator nicht vertraut sind, können meinen vorherigen Artikel lesen: Generator-Erklärung; Nach einem Vergleich haben wir Folgendes festgestellt: Async-Funktion ist die Generatorfunktion. Ersetzen Sie das Sternchen (*) durch „async“ und „yield“ durch „await“. Der Codevergleich lautet wie folgt:

// 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()

Das Implementierungsprinzip der asynchronen Funktion besteht darin, die Generatorfunktion und den automatischen Executor in eine Funktion zu packen.

<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>

Wir können die Schreibeigenschaften und den Stil von Generator und asynchronem Code analysieren:

<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高级教程

Das obige ist der detaillierte Inhalt vonEin tiefer Einblick in asynchrone Funktionen in JavaScript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:csdn.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen