Maison interface Web js tutoriel Introduction détaillée à l'exemple de code du modèle Promise de la programmation asynchrone JavaScript

Introduction détaillée à l'exemple de code du modèle Promise de la programmation asynchrone JavaScript

Mar 11, 2017 pm 03:19 PM

Le mode asynchrone devient de plus en plus important dans la programmation Web. Pour le langage Web grand public Javascript, ce mode n'est pas très facile à mettre en œuvre. Pour cette raison, de nombreuses bibliothèques Javascript (telles que jQuery et Dojo) ajoutent ce qu'on appelle. C'est une abstraction de promesse (parfois aussi appelée différée). Grâce à ces bibliothèques, les développeurs peuvent utiliser le modèle de promesse dans la programmation réelle. Le blog officiel d'IE a récemment publié un article détaillant comment utiliser XMLHttpRequest2 pour pratiquer le mode promesse. Jetons un coup d'œil aux concepts et applications associés.

Prenons un exemple où une page Web a des opérations asynchrones (via XMLHttpRequest2 ou Web Workers). Avec l'approfondissement de la technologie Web 2.0, le côté navigateur subit de plus en plus de pression informatique, la « concurrence » a donc une signification positive. Pour les développeurs, ils doivent non seulement maintenir intacte l'interaction entre la page et l'utilisateur, mais également coordonner la relation entre la page et les tâches asynchrones. Ce type d'exigences de programmation d'exécution non linéaire présente des difficultés d'adaptation. En mettant de côté l'interaction des pages, nous pouvons penser à deux résultats qui doivent être traités pour les appels asynchrones : le fonctionnement réussi et le traitement des échecs. Après un appel réussi, nous devrons peut-être utiliser le résultat renvoyé dans une autre requête Ajax, ce qui provoquera une situation de « chaîne de fonctions » (détaillée dans l'autre article de l'auteur « Explication du style de programmation asynchrone de NodeJS »). Cette situation crée une complexité de programmation. Jetez un œil à l'exemple de code suivant (basé sur XMLHttpRequest2) :

function searchTwitter(term, onload, onerror) {

     var xhr, results, url;
     url = 'http://search.twitter.com/search.json?rpp=100&q=' + term;
     xhr = new XMLHttpRequest();
     xhr.open('GET', url, true);

     xhr.onload = function (e) {
         if (this.status === 200) {
             results = JSON.parse(this.responseText);
             onload(results);
         }
     };

     xhr.onerror = function (e) {
         onerror(e);
     };

     xhr.send();
 }

 function handleError(error) {
     /* handle the error */
 }

 function concatResults() {
     /* order tweets by date */
 }

 function loadTweets() {
     var container = document.getElementById('container');

     searchTwitter('#IE10', function (data1) {
         searchTwitter('#IE9', function (data2) {
             /* Reshuffle due to date */
             var totalResults = concatResults(data1.results, data2.results);
             totalResults.forEach(function (tweet) {
                 var el = document.createElement('li');
                 el.innerText = tweet.text;
                 container.appendChild(el);
             });
         }, handleError);
     }, handleError);
 }
Copier après la connexion

La fonction du code ci-dessus est d'obtenir le contenu avec les hashtags IE10 et IE9 dans Twitter et de l'afficher sur la page. Ce type de fonction de rappel imbriquée est difficile à comprendre. Les développeurs doivent analyser soigneusement quel code est utilisé pour la logique métier de l'application et quel code gère les appels de fonction asynchrones. La structure du code est fragmentée. La gestion des erreurs est également décomposée. Nous devons détecter l'apparition d'erreurs à divers endroits et les gérer en conséquence.

Pour réduire la complexité de la programmation asynchrone, les développeurs recherchent des moyens simples de gérer les opérations asynchrones. L'un de ces modèles de traitement est appelé promesse et représente le résultat d'une opération qui peut être de longue durée et ne doit pas nécessairement être complète. Au lieu de bloquer et d'attendre la fin d'une longue opération, ce modèle renvoie un objet qui représente le résultat promis.

Prenons un exemple où le code de la page doit accéder à une API tierce. Les retards du réseau peuvent entraîner des temps de réponse plus longs. Dans ce cas, l'utilisation de la programmation asynchrone n'affectera pas l'interaction entre la page entière et l'utilisateur. Le mode promesse implémente généralement une méthode appelée ensuite pour enregistrer la fonction de rappel correspondante lorsque l'état change. Par exemple, l'exemple de code suivant :

searchTwitter(term).then(filterResults).then(displayResults);
Copier après la connexion

Le mode promesse est à tout moment dans l'un des trois états suivants : non rempli, résolu et rejeté. En prenant la norme CommonJS Promise/A comme exemple, la méthode then sur l'objet promise est chargée d'ajouter des fonctions de traitement pour les états terminés et rejetés. La méthode then renverra un autre objet de promesse pour faciliter la formation d'un pipeline de promesse.Cette méthode de renvoi d'objets de promesse peut aider les développeurs à enchaîner des opérations asynchrones, telles que then(resolvedHandler, rejetéHandler);. La fonction de rappel wantedHandler est déclenchée lorsque l'objet de promesse entre dans l'état d'achèvement et fournit le résultat ; la fonction rejetéeHandler est appelée dans l'état de rejet.

Avec le modèle de promesse, nous pouvons réimplémenter l'exemple Twitter ci-dessus. Afin de mieux comprendre la méthode de mise en œuvre, nous avons essayé de créer un cadre de modèles de promesse à partir de zéro. Vous avez d’abord besoin de quelques objets pour stocker les promesses.

var Promise = function () {
        /* initialize promise */
    };
Copier après la connexion

Ensuite, définissez la méthode then, qui accepte deux paramètres pour gérer l'état d'achèvement et de rejet.

Promise.prototype.then = function (onResolved, onRejected) {
     /* invoke handlers based upon state transition */
 };
Copier après la connexion

En même temps, deux méthodes sont nécessaires pour exécuter la transition de statut d'incomplet à terminé et d'incomplet à rejeté.

Promise.prototype.resolve = function (value) {
     /* move from unfulfilled to resolved */
 };

 Promise.prototype.reject = function (error) {
     /* move from unfulfilled to rejected */
 };
Copier après la connexion

Maintenant qu'une étagère de promesses a été construite, nous pouvons continuer l'exemple ci-dessus, en supposant que nous obtenons uniquement le contenu d'IE10. Créez une méthode pour envoyer la requête Ajax et enveloppez-la dans une promesse. Cet objet de promesse spécifie le processus de transition de l'état d'achèvement et de rejet dans xhr.onload et xhr.onerror respectivement. Veuillez noter que la fonction searchTwitter renvoie l'objet de promesse. Ensuite, dans loadTweets, utilisez la méthode then pour définir les fonctions de rappel correspondant à l'état d'achèvement et de rejet.

function searchTwitter(term) {

    var url, xhr, results, promise;
    url = 'http://search.twitter.com/search.json?rpp=100&q=' + term;
    promise = new Promise();
    xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);

    xhr.onload = function (e) {
        if (this.status === 200) {
            results = JSON.parse(this.responseText);
            promise.resolve(results);
        }
    };

    xhr.onerror = function (e) {
        promise.reject(e);
    };

    xhr.send();
    return promise;
}

function loadTweets() {
    var container = document.getElementById('container');
    searchTwitter('#IE10').then(function (data) {
        data.results.forEach(function (tweet) {
            var el = document.createElement('li');
            el.innerText = tweet.text;
            container.appendChild(el);
        });
    }, handleError);
}
Copier après la connexion

Jusqu'à présent, nous pouvons appliquer le mode promesse à une seule requête Ajax, mais il semble que les avantages de la promesse ne soient pas reflétés. Jetons un coup d'œil à la collaboration simultanée de plusieurs requêtes Ajax. À ce stade, nous avons besoin d’une autre méthode pour stocker l’objet promis prêt à être appelé. Une fois qu'une promesse est convertie de l'état incomplet à l'état terminé ou rejeté, la fonction de gestionnaire correspondante dans la méthode then sera appelée. La méthode when est importante lorsque vous devez attendre la fin de toutes les opérations.

Promise.when = function () {
    /* handle promises arguments and queue each */
};
Copier après la connexion

En prenant comme exemple le scénario où nous venons d'obtenir deux éléments de contenu d'IE10 et IE9, nous pouvons écrire le code comme ceci :

var container, promise1, promise2;
container = document.getElementById('container');
promise1 = searchTwitter('#IE10');
promise2 = searchTwitter('#IE9');
Promise.when(promise1, promise2).then(function (data1, data2) {

    /* Reshuffle due to date */
    var totalResults = concatResults(data1.results, data2.results);
    totalResults.forEach(function (tweet) {
        var el = document.createElement('li');
        el.innerText = tweet.text;
        container.appendChild(el);
    });
}, handleError);
Copier après la connexion

分析上面的代码可知,when函数会等待两个promise对象的状态发生变化再做具体的处理。在实际的Promise库中,when函数有很多变种,比如 when.some()、when.all()、when.any()等,读者从函数名字中大概能猜出几分意思来,详细的说明可以参考CommonJS的一个promise实现when.js。

除了CommonJS,其他主流的Javascript框架如jQuery、Dojo等都存在自己的promise实现。开发人员应该好好利用这种模式来降低异步编程的复杂性。我们选取Dojo为例,看一看它的实现有什么异同。

Dojo框架里实现promise模式的对象是Deferred,该对象也有then函数用于处理完成和拒绝状态并支持串联,同时还有resolve和reject,功能如之前所述。下面的代码完成了Twitter的场景:

function searchTwitter(term) {

    var url, xhr, results, def;
    url = 'http://search.twitter.com/search.json?rpp=100&q=' + term;
    def = new dojo.Deferred();
    xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);

    xhr.onload = function (e) {
        if (this.status === 200) {
            results = JSON.parse(this.responseText);
            def.resolve(results);
        }
    };

    xhr.onerror = function (e) {
        def.reject(e);
    };

    xhr.send();
    return def;
}

dojo.ready(function () {
    var container = dojo.byId('container');
    searchTwitter('#IE10').then(function (data) {
        data.results.forEach(function (tweet) {
            dojo.create('li', {
                innerHTML: tweet.text
            }, container);
        });
    });
});
Copier après la connexion

不仅如此,类似dojo.xhrGet方法返回的即是dojo.Deferred对象,所以无须自己包装promise模式。

var deferred = dojo.xhrGet({
    url: "search.json",
    handleAs: "json"
});

deferred.then(function (data) {
    /* handle results */
}, function (error) {
    /* handle error */
});
Copier après la connexion

除此之外,Dojo还引入了dojo.DeferredList,支持开发人员同时处理多个dojo.Deferred对象,这其实就是上面所提到的when方法的另一种表现形式。

dojo.require("dojo.DeferredList");
dojo.ready(function () {
    var container, def1, def2, defs;
    container = dojo.byId('container');
    def1 = searchTwitter('#IE10');
    def2 = searchTwitter('#IE9');

    defs = new dojo.DeferredList([def1, def2]);

    defs.then(function (data) {
        // Handle exceptions
        if (!results[0][0] || !results[1][0]) {
            dojo.create("li", {
                innerHTML: 'an error occurred'
            }, container);
            return;
        }
        var totalResults = concatResults(data[0][1].results, data[1][1].results);

        totalResults.forEach(function (tweet) {
            dojo.create("li", {
                innerHTML: tweet.text
            }, container);
        });
    });
});
Copier après la connexion

上面的代码比较清楚,不再详述。

说到这里,读者可能已经对promise模式有了一个比较完整的了解,异步编程会变得越来越重要,在这种情况下,我们需要找到办法来降低复杂度,promise模式就是一个很好的例子,它的风格比较人性化,而且主流的JS框架提供了自己的实现。所以在编程实践中,开发人员应该尝试这种便捷的编程技巧。需要注意的是,promise模式的使用需要恰当地设置promise对象,在对应的事件中调用状态转换函数,并且在最后返回promise对象。

技术社区对异步编程的关注也在升温,国内社区也发出了自己的声音。资深技术专家老赵就发布了一套开源的异步开发辅助库Jscex,它的设计很巧妙,抛弃了回调函数的编程方式,采用一种“线性编码、异步执行”的思想,感兴趣的读者可以查看这里。

不仅仅是前端的JS库,如今火热的NodeJS平台也出现了许多第三方的promise模块,具体的清单可以访问这里。

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!

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

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Vous avez un jeu croisé?
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment implémenter la programmation asynchrone avec les fonctions C++ ? Comment implémenter la programmation asynchrone avec les fonctions C++ ? Apr 27, 2024 pm 09:09 PM

Résumé : La programmation asynchrone en C++ permet d'effectuer plusieurs tâches sans attendre des opérations fastidieuses. Utilisez des pointeurs de fonction pour créer des pointeurs vers des fonctions. La fonction de rappel est appelée lorsque l'opération asynchrone est terminée. Les bibliothèques telles que boost::asio fournissent un support de programmation asynchrone. Le cas pratique montre comment utiliser les pointeurs de fonction et boost::asio pour implémenter des requêtes réseau asynchrones.

Tenir parole : les avantages et les inconvénients de tenir ses promesses Tenir parole : les avantages et les inconvénients de tenir ses promesses Feb 18, 2024 pm 08:06 PM

Dans la vie quotidienne, nous rencontrons souvent des problèmes entre promesses et réalisation. Que ce soit dans une relation personnelle ou dans une transaction commerciale, tenir ses promesses est essentiel pour instaurer la confiance. Cependant, les avantages et les inconvénients de l’engagement sont souvent controversés. Cet article explorera les avantages et les inconvénients des engagements et donnera quelques conseils sur la façon de tenir parole. Les avantages promis sont évidents. Premièrement, l’engagement renforce la confiance. Lorsqu’une personne tient parole, elle fait croire aux autres qu’elle est une personne digne de confiance. La confiance est le lien établi entre les personnes, qui peut les rendre plus

Tutoriel JavaScript simple : Comment obtenir le code d'état HTTP Tutoriel JavaScript simple : Comment obtenir le code d'état HTTP Jan 05, 2024 pm 06:08 PM

Tutoriel JavaScript : Comment obtenir le code d'état HTTP, des exemples de code spécifiques sont requis Préface : Dans le développement Web, l'interaction des données avec le serveur est souvent impliquée. Lors de la communication avec le serveur, nous devons souvent obtenir le code d'état HTTP renvoyé pour déterminer si l'opération a réussi et effectuer le traitement correspondant en fonction de différents codes d'état. Cet article vous apprendra comment utiliser JavaScript pour obtenir des codes d'état HTTP et fournira quelques exemples de codes pratiques. Utilisation de XMLHttpRequest

Problèmes courants et solutions dans la programmation asynchrone dans le framework Java Problèmes courants et solutions dans la programmation asynchrone dans le framework Java Jun 04, 2024 pm 05:09 PM

3 problèmes et solutions courants dans la programmation asynchrone dans les frameworks Java : Callback Hell : utilisez Promise ou CompletableFuture pour gérer les rappels dans un style plus intuitif. Conflit de ressources : utilisez des primitives de synchronisation (telles que des verrous) pour protéger les ressources partagées et envisagez d'utiliser des collections thread-safe (telles que ConcurrentHashMap). Exceptions non gérées : gérez explicitement les exceptions dans les tâches et utilisez un cadre de gestion des exceptions (tel que CompletableFuture.exceptionally()) pour gérer les exceptions.

En savoir plus sur Promise.resolve() En savoir plus sur Promise.resolve() Feb 18, 2024 pm 07:13 PM

Une explication détaillée de Promise.resolve() nécessite des exemples de code spécifiques. Promise est un mécanisme en JavaScript pour gérer les opérations asynchrones. Dans le développement réel, il est souvent nécessaire de traiter certaines tâches asynchrones qui doivent être exécutées dans l'ordre, et la méthode Promise.resolve() est utilisée pour renvoyer un objet Promise qui a été rempli. Promise.resolve() est une méthode statique de la classe Promise, qui accepte un

Comment le framework Golang gère-t-il la concurrence et la programmation asynchrone ? Comment le framework Golang gère-t-il la concurrence et la programmation asynchrone ? Jun 02, 2024 pm 07:49 PM

Le framework Go utilise les fonctionnalités de concurrence et asynchrones de Go pour fournir un mécanisme permettant de gérer efficacement les tâches simultanées et asynchrones : 1. La concurrence est obtenue via Goroutine, permettant d'exécuter plusieurs tâches en même temps. 2. La programmation asynchrone est implémentée via des canaux, qui peut être exécuté sans bloquer le thread principal;3. Convient aux scénarios pratiques, tels que le traitement simultané des requêtes HTTP, l'acquisition asynchrone des données de base de données, etc.

Comment obtenir facilement le code d'état HTTP en JavaScript Comment obtenir facilement le code d'état HTTP en JavaScript Jan 05, 2024 pm 01:37 PM

Introduction à la méthode d'obtention du code d'état HTTP en JavaScript : Dans le développement front-end, nous devons souvent gérer l'interaction avec l'interface back-end, et le code d'état HTTP en est une partie très importante. Comprendre et obtenir les codes d'état HTTP nous aide à mieux gérer les données renvoyées par l'interface. Cet article explique comment utiliser JavaScript pour obtenir des codes d'état HTTP et fournit des exemples de code spécifiques. 1. Qu'est-ce que le code d'état HTTP ? Le code d'état HTTP signifie que lorsque le navigateur lance une requête au serveur, le service

Quels sont les avantages et les inconvénients de la programmation asynchrone en PHP ? Quels sont les avantages et les inconvénients de la programmation asynchrone en PHP ? May 06, 2024 pm 10:00 PM

Les avantages de la programmation asynchrone en PHP incluent un débit plus élevé, une latence plus faible, une meilleure utilisation des ressources et une évolutivité. Les inconvénients incluent la complexité, la difficulté de débogage et la prise en charge limitée des bibliothèques. Dans le cas réel, ReactPHP est utilisé pour gérer les connexions WebSocket, démontrant l'application pratique de la programmation asynchrone.

See all articles