- Implémentation simple d'idées de contrôle de processus asynchrone basées sur es6 : spécification Promise/A+
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 }) }); });
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.
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,
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 :
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});
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(){ } }
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 = =
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则是失败态
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; }
Deferred =.promise = = self = promise =((handler = promise.queue.shift())){ (handler && res = handler.fulfilled.apply(self,args); (res && res.isPromise){ res.queue ==
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 ==
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); //调用完成态回调函数 } } } }
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 à nouveauCe 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!