——非同期プロセス制御の考え方をシンプルに実装するためのes6: Promise/A+仕様に基づく
nodejsの強力な非同期処理機能により、それをベースにしたアプリケーションが引き続き登場します。増加しますが、非同期です。結果としてネストされた理解しにくいコードが生成されるため、nodejs はエレガントさが失われ、肥大化したように見えます。これに似たコード:
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 }) }); });
値オブジェクトは上記のコードの println で定義されており、関連する値を渡すために 500 秒の遅延でコールバックが呼び出されます。
最初に println を呼び出して「ztf」を渡します。 ", 次の実行関数が依存していると仮定して 今回返された値で、呼び出しは上記のコードになります。 ztf を渡して abc を返します。 abc を使用して def を返します。 def を使用して 1 を返します。
nodejs は次のように使用されているためサーバーでは、さまざまなデータベース クエリを使用することが不可欠です。データベース クエリにはさらに多くの依存関係があります。たとえば、特定のユーザーの権限をクエリする必要がある場合、3 つの手順が必要です
① ID でユーザーを検索します
② 検索します。返されたユーザー ロール ID による対応するロール
③ ロールを通じて、対応する権限を見つけます
これには 3 レベルの入れ子関係が必要で、コードは上記とほぼ同じです。
Promiseは非同期操作の最終結果を表します。 未完了状態、完了状態(resolve)、失敗状態(reject)の3つの状態があります状態は不可逆であり、完了状態は未完了に戻ることはできず、失敗状態は完了状態になることはありません
主に対話方法は、その then メソッドでコールバック関数を渡してチェーン呼び出しを形成することです。
まず、Promise/A+ 仕様が特定のアプリケーションでどのように呼び出されるかを見てみましょう:
Promise 仕様に従うには、上記の例を次のように変更します。
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});
このコードは、then() メソッドのチェーン呼び出しを通じて、非同期コードの連続的なネストの現状をある程度変更します。プロセス制御を実現できます。
//处理回调var Promise = function(){this.queue = []; //存储的是回调函数的队列this.isPromise = true; }//延迟对象var Deferred = function(){this.promise = new Promise(); } Deferred.prototype = {//托管了callback回调函数 callback:function(){ },//完成态 resolve:function(){ },//失败态 reject:function(){ } }
ここでは、Promise と Deferred の 2 つのオブジェクトが定義されています。Promise は、その名前が示すように、遅延オブジェクトを処理します。
Promise =.queue = []; .isPromise = = handler =((fulfilledHandler) == =((errorHandler) == = Deferred =.promise = =
Promise.then メソッドはコールバックをキューに挿入するだけで、1 つは完了状態で実行され、もう 1 つは失敗状態で実行されることがわかります。
プロセス全体を完了するには、Deferredで完了状態と失敗状態の処理メソッドを定義する必要もあります:
//处理内部操作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 ==
完了状態の操作を追加し、このコードは によって渡されたコールバック関数のコレクションを取得します。次に、promise.queue while 呼び出し、現在の引数を渡します
次に、完了状態をマネージド コールバック関数 (Deferred.callback()) に入れて、ロジックに従って実行する必要があります:
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 ==
コードはここにあります。メイン関数は完了していますが、失敗状態がまだ追加されていません。その実装は、二次的な入れ子がないことを除いて成功状態と似ています:
//处理内部操作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); //调用完成态回调函数 } } } }
重要なポイント:
①各オペレーションは同じPromiseオブジェクトを返し、チェーンオペレーションを保証します
②関数コールバックの最初のパラメータは、エラーがなければnullです
③各チェーンはthenメソッドを介して接続され、戻ります。再度実行されるPromiseオブジェクト
以上がes6: 非同期プロセス制御のアイデアに基づくの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。