6

C++ の "const ポイズニング" を覚えていますか? 1 つのメソッドを としてマークすると、そのメソッドが呼び出したすべてのメソッドを次のようにマークし、次にそれらが呼び出すすべてのメソッドを次のconstようにマークする必要があることに気付きました。const

Javascript で非同期ポイズニングに問題がありますが、関連性はないと思いますが、ダウンではなくアップに伝播します。関数が非同期関数を呼び出す可能性がある場合は、それ自体を非同期として書き直す必要があり、それを呼び出すすべての関数を非同期にする必要があります。

ここには整形式の質問はありません(申し訳ありませんが、モッズ)が、誰かが(a)アドバイスまたは(b)(a)を持つ可能性のある参照のいずれかを持っていることを望んでいました。

4

3 に答える 3

2

悪い質問ではありません。ただし、制御の流れを完全に台無しにしなければならないことを回避する方法がいくつかあります。注:私はそれがきれいだとは言いませんでした。

オブジェクトA、B、C、Dがあり、A.Amethod何も返さず、BのメソッドgetBDataを呼び出し、BgetCDataがCのメソッドを呼び出し、問題はCがDを次のように呼び出していたとします。

var data = D.getRawData();
... something to be done with data ...
... something else to be done with data...

そして今、それは次のように書かれなければなりません

D.getData(function(data){
  ... something to be done with data ...
  ... something else to be done with data...  
});

各メソッドにいつでもコールバック パラメータを追加できるので、以前のコードは次のようになりました。

 var A = {  
//I'm not recommending coding like this, just for demonstration purposes.
 ...
    Amethod: function(x,y,z){
        var somethingForA = this.B.getBData(1,2,3);
        astatement1;
        astatement2;
        ...
     }
  ...
  }    
  //end of A
  ...
 var B = {  
 ...
    Bmethod: function(x,y,z){
        var somethingForB = this.C.getCData(1,2,3);
        bstatement1;
        var somethingFromB = bstatement2;
        return somethingFromB;
     }
  ...
  }    
  //end of B
  ...
 var C = {  
 ...
    Cmethod: function(x,y,z){
        var somethingForC =  this.D.getRawData(1,2,3)
        cstatement1;
        var somethingFromC = cstatement2;
        return somethingFromC;
     }
  ...
  }    
  //end of C
  ...

あなたは今持っているでしょう:

 var A = {  
  ...
    Amethod: function(x,y,z){
        this.B.getBData((1,2,3,function(somethingForA){
            astatement1;
            astatement2;
        });
        ...
     }
  ...
  }    
  //end of A
  ...
 var B = {  
 ...
    Bmethod: function(x,y,z,callback){
        this.C.getCData(1,2,3,function(somethingForB){
          bstatement1;
          var somethingFromB = bstatement2;
           callback(somethingFromB);
        });
        ...
     }
  ...
  }    
  //end of B
  ...
 var C = {  
 ...
    Cmethod: function(x,y,z,callback){
        this.D.getRawData(1,2,3,function(somethingForC) {
           cstatement1;
           var somethingFromC = cstatement2;
           callback(somethingFromC);
        });
     }
  ...
  }    
  //end of C
  ...

これは、無名関数を使用してすべての機能を実装し、制御の流れを維持する、ほぼ単純なリファクタリングです。それがどれほど文字通りの変換になるかはわかりません。変数のスコープを調整する必要がある場合があります。そして明らかに、それはそれほどきれいではありません。

他の方法はありますか?もちろん。ご覧のとおり、上記はごちゃごちゃしているので、ごちゃごちゃしたコードを書かないようにしたいと思います。どのくらい乱雑ではないかは、コンテキストによって異なります。

コールバック パラメータを渡す必要はありません。必要なコールバックは事前にオブジェクトに渡すことができます。または、パラメータ内の項目の 1 つとして渡すこともできます。コールバックは直接呼び出す必要はないかもしれませんが、利用可能なさまざまなイベント処理メソッドの 1 つを使用して間接的に呼び出すことができます (そのために使用したいライブラリを確認する必要があります)。イベントがトリガーされます。または、仲介者 B と C を完全に回避するために、データが「取得」されるたびに A がコールバックを登録できるグローバルな「DataGetter」があるかもしれません。

最後に、非同期でのみ取得できる何かが必要であり、そのデータをコマンド チェーンに渡さなければならないことを発見するためだけに呼び出しにひざまずく場合は、次の点で少し逆方向に何かをしている可能性があるという考慮事項があります。どのオブジェクトがプログラム ロジックのフローを制御する必要があるか (ただし、このシナリオに問題があると思われる理由をどのように説明すればよいかについては、正直なところ困惑しています)。A のインスタンスには B のインスタンスが含まれている必要があり、B には C のインスタンスが含まれている必要があるため、構成の一部としてサブインスタンスを作成するインスタンスは、サブインスタンスがどのように生成されるかについてある程度の制御が必要であると考える傾向があります。サブインスタンスに完全に決定させるのではなく、自分自身で....それが理にかなっている場合:-(

At this point I feel like I'm rambling a bit so... here's to hoping somebody would explain the issues better than me!

于 2012-04-06T03:37:24.307 に答える
0

問題が b() が完了するまでブロックする必要があるが非同期の a() を呼び出す場合、おそらく a() からのコールバックがフラグを設定し、b() がフラグを監視する可能性があります。a() がコールバックを提供しない場合、a() が完了すると変更される値がどこかにある可能性があります。

于 2012-04-06T01:09:10.223 に答える