Maison > interface Web > js tutoriel > Basé sur es6 : idée de contrôle de processus asynchrone

Basé sur es6 : idée de contrôle de processus asynchrone

零下一度
Libérer: 2017-06-26 09:10:04
original
1427 Les gens l'ont consulté

- Implémentation simple d'idées de contrôle de processus asynchrone basées sur es6 : spécification Promise/A+

Avant-propos :

Les puissantes capacités de traitement asynchrone de nodejs en font un excellent choix côté serveur C'est génial, et le nombre d'applications basées sur celui-ci continue d'augmenter, mais le code imbriqué et difficile à comprendre provoqué par l'asynchronie rend les nodejs moins élégants et gonflés. Code similaire à celui-ci :

function println(name,callback){var value = {"ztf":"abc","abc":"def","def":1}
    setTimeout(function(){
        callback(value[name]);
    },500);
}

println("ztf",function(name){ 
    println(name,function(res){
        console.log(res);//def        println(res,function(res1){
            console.log(res1);//1        })
    });
});
Copier après la connexion

L'objet valeur est défini dans println du code ci-dessus, et le rappel est appelé avec un délai de cinq cents secondes pour transmettre la valeur appropriée .

Appelez d'abord println et transmettez "ztf". En supposant que la fonction d'exécution suivante dépend de la valeur renvoyée cette fois, l'appel devient le code ci-dessus et renvoie abc. . Utilisez def pour renvoyer 1;

Étant donné que nodejs est utilisé comme serveur, diverses requêtes de base de données sont essentielles. Par exemple, si je dois interroger les autorisations d'un certain utilisateur, alors trois. des étapes sont nécessaires

 ① Rechercher l'utilisateur par identifiant

 ② Rechercher le rôle correspondant par l'identifiant de rôle d'utilisateur renvoyé

 ③ Rechercher l'autorisation correspondante par rôle

Trois niveaux de relations imbriquées sont nécessaires ici. Le code est presque le même que ci-dessus.

spécification promesse/A+

La promesse représente le résultat final d'une opération asynchrone. Il a trois états, à savoir état inachevé, état terminé (résolution), état échoué (rejet) L'état est irréversible, l'état terminé ne peut pas revenir à l'état inachevé et l'état échoué ne peut pas devenir un état terminé

 

Le principal moyen d'interagir avec promise est de transmettre la fonction de rappel dans sa méthode then pour former un appel en chaîne,

 

 

Implémentation

Tout d'abord, regardons comment la spécification Promise/A+ est appelée dans des applications spécifiques :

Nous pouvons changer l'exemple ci-dessus en :

basé sur la spécification de la promesse
var  printText = function(name){var deferred = new Deferred(); //new一个托管函数println(name,deferred.callback());//把回调函数托管到Deferred中实现return deferred.promise; //返回promise对象实现链式调用}

printText("ztf")
.then(function(name){
    console.log(name);return printText(name); //第二次调用依赖第一次调用 返回promise对象  在成功态中判断
})
.then(function(res){
    console.log(res);//defreturn printText(res);
})
.then(function(res1){
    console.log(res1);//1});
Copier après la connexion

Dans une certaine mesure, un tel code modifie le statu quo de l'imbrication continue du code asynchrone Grâce à l'appel en chaîne de la méthode then(), le contrôle du processus de. le code asynchrone est obtenu.

//处理回调var Promise = function(){this.queue = []; //存储的是回调函数的队列this.isPromise = true; 
}//延迟对象var Deferred = function(){this.promise = new Promise();
}
Deferred.prototype = {//托管了callback回调函数    callback:function(){
        
    },//完成态    resolve:function(){
        
    },//失败态    reject:function(){
        
    }
}
Copier après la connexion

Deux objets sont définis ici, Promise et Deferred, qui sont responsables du traitement de la distribution des fonctions Deferred, comme son nom l'indique, gère les retards. objets.

 Promise =.queue = []; .isPromise = = handler =((fulfilledHandler) == =((errorHandler) == =  Deferred =.promise = =
Copier après la connexion

Vous pouvez voir que la méthode Promise.then insère simplement le rappel dans la file d'attente, l'un est exécuté à l'état d'achèvement et l'autre est exécuté à l'état d'échec.

Afin de terminer l'ensemble du processus, vous devez également définir les méthodes de traitement d'achèvement et d'échec dans le Différé :

//处理内部操作var Promise = function(){this.queue = []; //存储的是回调函数的队列this.isPromise = true; 
}
Promise.prototype = {//then方法 fulfilledHandler是完成态时执行的回调函数 errorHandler则是失败态
Copier après la connexion
  then:function(fulfilledHandler,errorHandler){
        var handler = {};
        if(typeof(fulfilledHandler) == "function"){
            handler.fulfilled = fulfilledHandler;
        }
        if(typeof(errorHandler) == "function"){
            handler.errored = errorHandler;
        }
     this.queue.push(handler);
        return this;
    }
Copier après la connexion
 
 Deferred =.promise = =   self =  promise =((handler = promise.queue.shift())){ (handler && res = handler.fulfilled.apply(self,args); (res && res.isPromise){ res.queue ==
Copier après la connexion

Ajout de l'opération d'état d'achèvement, ce code obtient l'ensemble des fonctions de rappel transmises par .then promise.queue while est appelé en séquence, en passant les arguments actuels

et nous devons ensuite mettre l'état d'achèvement dans l'état géré fonction de rappel (Deferred.callback() ), exécutez selon la logique :

 Promise =.queue = []; .isPromise = = handler =((fulfilledHandler) == =((errorHandler) == =  Deferred =.promise = = self =  args = Array.prototype.slice.call(arguments); = args.concat(Array.prototype.slice.call(arguments,));  self =  promise = args =((handler = promise.queue.shift())){ (handler && res = handler.fulfilled.apply(self,args); (res && res.isPromise){ res.queue ==
Copier après la connexion

Le code est ici La fonction principale est terminée, mais. l'état d'échec n'a pas été ajouté. Sa méthode de mise en œuvre est la même que celle de succès L'état est similaire sauf pour l'imbrication secondaire :

//处理内部操作var Promise = function(){this.queue = []; //存储的是回调函数的队列this.isPromise = true; 
}
Promise.prototype = {//then方法 fulfilledHandler是完成态时执行的回调函数 errorHandler则是失败态    then:function(fulfilledHandler,errorHandler){var handler = {};if(typeof(fulfilledHandler) == "function"){
            handler.fulfilled = fulfilledHandler;
        }if(typeof(errorHandler) == "function"){
            handler.errored = errorHandler;
        }this.queue.push(handler);return this;
    }
}//处理外部操作var Deferred = function(){this.promise = new Promise();
}
Deferred.prototype = {//托管了callback回调函数    callback:function(){var self = this;var args = Array.prototype.slice.call(arguments); //将arguments转为数组return function(err){if(err){//这里是失败态  传入了error对象                self.reject.call(self,err);return;
            }
            args = args.concat(Array.prototype.slice.call(arguments,1)); //合并外部arguments 与内部arguments 去掉err//这里是完成态            console.log(args);
            self.resolve.apply(self,args);
            
        }
    },//完成态    resolve:function(){var self = this;var promise = self.promise;var args = arguments;var handler;        while((handler = promise.queue.shift())){ //取出待执行队列中的第一个函数 直到全部执行完毕if(handler && handler.fulfilled){var res = handler.fulfilled.apply(self,args); //调用失败态回调函数if(res && res.isPromise){ //如果有二次嵌套 则再次执行promiseres.queue = promise.queue;
                    self.promise = res;return;
                }
            }
        }
    },//失败态    reject:function(err){var self = this;var promise = self.promise;var args = arguments;var handler;while((handler = promise.queue.shift())){ //取出待执行队列中的第一个函数 直到全部执行完毕if(handler && handler.errored){                var res = handler.fulfilled.call(self,err); //调用完成态回调函数                
                
            }
        }
    }
}
Copier après la connexion

Résumé

Clé. points :
① Chaque opération renvoie le même objet de promesse, garantissant l'opération de formule en chaîne

 ② Le premier paramètre du rappel de fonction est toujours l'objet d'erreur Si aucune erreur n'est signalée, null

<.> ③ Chaque chaîne est connectée via la méthode then et renvoie l'objet promis à exécuter à nouveau

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:php.cn
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