ホームページ > ウェブフロントエンド > jsチュートリアル > es6: 非同期プロセス制御のアイデアに基づく

es6: 非同期プロセス制御のアイデアに基づく

零下一度
リリース: 2017-06-26 09:10:04
オリジナル
1427 人が閲覧しました

——非同期プロセス制御の考え方をシンプルに実装するための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/A+仕様

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 サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート