Maison > interface Web > js tutoriel > le corps du texte

Une plongée approfondie dans les fonctions asynchrones en JavaScript

青灯夜游
Libérer: 2022-11-03 20:39:29
avant
1539 Les gens l'ont consulté

Une plongée approfondie dans les fonctions asynchrones en JavaScript

Fonction async

La valeur de retour de la fonction asynchrone est l'objet de promesse, et le résultat de l'objet de promesse est déterminé par la valeur de retour de l'exécution de la fonction asynchrone. La fonction async peut rendre les opérations asynchrones plus pratiques. En bref, c'est le sucre syntaxique de Generator.

Définissez une fonction asynchrone.La caractéristique est que même si le résultat de retour interne de la fonction n'est pas un objet de promesse, le résultat de retour final de l'appel de la fonction est toujours un objet de promesse. suit : Si le résultat renvoyé n'est pas un objet Promise Dans ce cas :

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

Si le résultat renvoyé est un objet Promise, nous pouvons utiliser la méthode then normalement, comme suit :

<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>
Copier après la connexion

await expression

Grâce à l'introduction ci-dessus d'async, j'ai l'impression que sa fonction est un peu insipide, en fait ce n'est pas le cas, mais async doit être utilisé avec wait pour obtenir l'effet de sucre syntaxique.

await caractéristiques : await doit être écrit dans la fonction asynchrone

await L'expression du côté droit est généralement un objet de promesse

await renvoie la valeur du succès de la promesse

la promesse d'attente a échoué, An une exception sera levée, qui doit être capturée et traitée via try...catch

Pour parler franchement : wait est équivalent à la première fonction de rappel de la méthode then, ne renvoyant que les valeurs réussies, et try pour les valeurs échouées ..catch à capturer. Une erreur générée dans la fonction asynchrone entraînera le rejet de l'objet Promise renvoyé. L'objet d'erreur généré sera reçu par la fonction de rappel de la méthode catch.

<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>
Copier après la connexion

Résumé :

(1)L'objet Promise derrière la commande wait peut être rejeté en conséquence, il est donc préférable de mettre la commande wait dans le code try...catch bloc.

(2)S'il y a des opérations asynchrones derrière plusieurs commandes d'attente, s'il n'y a pas de relation ultérieure, il est préférable de les laisser se déclencher en même temps. Par exemple : wait Promise.all([a(), b()]), voici une brève mention

(3)la commande wait ne peut être utilisée que dans des fonctions asynchrones, si elle est utilisée dans des fonctions ordinaires , Une erreur sera signalée.

(4)(Comprendre le principe de fonctionnement de l'async) La fonction asynchrone peut conserver la pile en cours d'exécution lorsqu'une tâche asynchrone est exécutée dans une fonction normale, si la tâche asynchrone se termine, la fonction normale peut avoir a terminé son exécution depuis longtemps et l'environnement de contexte de la tâche asynchrone a disparu. Si une tâche asynchrone signale une erreur, la pile d'erreurs n'inclura pas les fonctions ordinaires pendant l'exécution de la tâche asynchrone à l'intérieur de la fonction asynchrone, la fonction asynchrone suspend l'exécution, donc une fois que la tâche asynchrone à l'intérieur de la fonction asynchrone s'exécute et qu'une erreur est signalée, la pile d'erreurs inclura les fonctions asynchrones.

Formulaire d'utilisation 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 () => {};
Copier après la connexion

async lit les fichiers

Identique à la promesse de lire le contenu du fichier expliquée précédemment, nous pouvons également utiliser async pour lire le fichier, le code est le suivant :

// 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()
Copier après la connexion

async envoie des requêtes AJAX

Semblable à l'explication précédente de

promesse d'envoi de requêtes ajax

, nous pouvons également utiliser async pour envoyer des requêtes ajax. Le code est le suivant :

Par rapport à Generator

. Nous avons constaté que la relation entre async et wait est très similaire à la relation entre Generator et rendement. Les amis qui ne connaissent pas Generator peuvent lire mon article précédent :

Generator Explanation

après une comparaison, nous avons trouvé que : la fonction async ; est la fonction Générateur Remplacez l'astérisque (*) par async et remplacez rendement par wait. La comparaison de code est la suivante :

Le principe d'implémentation de la fonction asynchrone est d'envelopper la fonction Générateur et l'exécuteur automatique dans une fonction.

<script>
    async function fn(args) {}
    // 等同于
    function fn(args) {
        // spawn函数就是自动执行器
        return spawn(function* () {});
    }
</script>
Copier après la connexion

Nous pouvons analyser les caractéristiques et le style d'écriture du générateur et du code asynchrone :

<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>
Copier après la connexion

所以 async 函数的实现符合语义也很简洁,不用写Generator的自动执行器,改在语言底层提供,因此代码量少。 

从上文代码我们可以总结以下几点

(1)Generator函数执行需要借助执行器,而async函数自带执行器,即async不需要像生成器一样需要借助 next 方法才能执行,而是会自动执行。

(2)相比于生成器函数,我们可以看到 async 函数的语义更加清晰

(3)上面就说了,async函数可以接受Promise或者其他原始类型,而生成器函数yield命令后面只能是Promise对象或者Thunk函数。

(4)async函数返回值只能是Promise对象,而生成器函数返回值是 Iterator 对象

【推荐学习:javascript高级教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:csdn.net
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal