3

Node.jsの非同期フローに苦労しています。以下のクラスがあるとします。

function myClass() {
  var property = 'something';
  var hasConnected = false;

  this.connect = function(params) {
    //Some logic that connects to db and in callback returns if the connection is successful
    connectToSomeDB('ConnectionString', function(connectionResult) {
      hasConnected = connectionResult
    })
  };

  this.get = function(params) {
    if(hasConnected) {
      DoGetOperation() //
    }
    else {
      //Another question. What should be done here. Call the connect again?
    }
  }
}

Javascript と Node 構造を考慮すると、私の設計にはいくつかの大きな問題があると確信していますが、操作が適切に機能するためにconnect 呼び出す必要があるため、方法を理解できません。しかし、操作後にログを記録すると、次のようになります。

brandNewObject = myClass();
brandNewObject.connect();
brandNewObject.get();

isConnectedグローバル変数を取得する前に get 関数が呼び出されていることがわかります。実際に Node の非同期構造に反することなく、これを機能させるにはどうすればよいですか?

理想的には、私が探している解決策は、コールバックの「外部クラス」を定義するのではなく、実際に内部で「接続」を処理することです

4

3 に答える 3

1

これにはさまざまな回避策があります。

1つの簡単な方法は、あなたがしていることに似ています

this.get = function(params) {
    if (hasConnected) {
        DoGetOperation(params);
    } else {
        //here you can check the status of the connect. if it is still in 
        //progress do nothing. if the connection has failed for some reason
        //you can retry it. Otherwise send a response back indicating that the
        //operation is in progress.
    }
}

もう 1 つの方法は、get 関数に同じ非同期コールバック メカニズムを使用することです。これにより、メソッド シグネチャが次のように変更されます。

this.deferredOperations = new Array();

this.get = function(params, callback) {
    if (hasConnected) {
       //using a callback as an optional parameter makes the least 
       //impact on your current function signature. 
       //If a callback is present send the data back through it, 
       //otherwise this function simply returns the value (acts synchronously).
       if (callback !== null) {
         callback(DoGetOperation(params));
       } else {
         return DoGetOperation(params);
       }
    } else {
       this.deferredOperations.push([params,callback]);
    }
}

//connect changes now
this.connect = function(params) {
//Some logic that connects to db and in callback returns if the connection is successful
connectToSomeDB('ConnectionString', function(connectionResult) {
  hasConnected = connectionResult;
  if (hasConnected && this.deferredOperations.length > 0) {
    for (var i=0; i < this.deferredOperations.length; i++) {
      var paramFunction = this.deferredOperations.pop();
      var params = paramFunction[0];
      var func = paramFunction[1];
      DoAsyncGetOperation(params, func); //Need to write a new function that accepts a callback
    }
  }
})
};

HTH

于 2013-01-16T10:20:56.480 に答える
1

コールバックを使用する必要があります。

function myClass() {
  var property = 'something';
  var hasConnected = false;

  // added second parameter
  this.connect = function(params, callback) {
    //Some logic that connects to db and in callback returns if the connection is successful
    connectToSomeDB('ConnectionString', function(connectionResult) {
      hasConnected = connectionResult;
      // Now call the callback!
      callback();
    })
  };

  this.get = function(params) {
    if(hasConnected) {
      DoGetOperation() //
    }
    else {
      //Another question. What should be done here. Call the connect again?
    }
  }
}
brandNewObject = myClass();
brandNewObject.connect({}, function () {
  // this function gets called after a connection is established
  brandNewObject.get();
});
于 2013-01-16T10:08:04.197 に答える
1

メソッドにコールバック パラメータを追加しますconnect

  this.connect = function(params, callback) {
    //Some logic that connects to db and in callback returns if the connection is successful
    connectToSomeDB('ConnectionString', function(connectionResult) {
      hasConnected = connectionResult;

      // Call the callback provided
      callback(params);
    })
  };

次に、次のように呼び出すことができます。

brandNewObject = myClass();
brandNewObject.connect({}, function(/* optionally, "params" */) {
    brandNewObject.get();
});
于 2013-01-16T10:08:24.197 に答える