0

私は Dojo をかなり使ってきましたが、完全には頭に入っていませんdojo.Deferred(少なくとも、利用可能なすべての機能を使用したわけではありません)。私はそれについていくつか読んでいて、次のシナリオが Deferred をよりエレガントなアプローチとして使用するのに適した場所になるかどうか疑問に思っていましたか? または、Deferred でない場合Promise、dojo で利用できる、またはより読みやすい/シーケンシャルな方法で以下を達成できる他の種類の連鎖手法はありますか?

var _this = this;

var secondCallback =  function( res ) {
    console.debug('All is complete Result [' + res +']');
};

var firstCallback = function( res ) {
    if(res == 'true') 
        my.lib.processRPC( my.rpc.module.DoSecondStep( _this.user_id ), secondCallback );
};

my.lib.processRPC( my.rpc.module.CheckFirstStep(), firstCallback );

もしそうなら、これはどのように見えますか?ここで Deferred をどのように使用しますか? どんな助けでも大歓迎です。

4

2 に答える 2

1

ネットワーク遅延後の非同期コールバックをシミュレートする単純な window.setTimeout を使用して RPC モジュールをダミー化し、_this.user_id を _this_user_id に置き換え、場合によってはその他の微調整を行いました。

実行可能な例: http://dojo-sandbox.net/public/4c296/0

/* In resopnse to http://stackoverflow.com/questions/11217904/how-to-elegantly-structure-a-chain-of-requests-callbacks-using-dojo */
require([
  "dojo/_base/Deferred"
], function(Deferred) {

  var my_lib = function() {};
  my_lib.processRPC = function(value, def) {
    // simulate a long lived network call or whatever
    window.setTimeout(function() {
      console.log("rpc  has fired");
      def.resolve(value);
    }, 1000);
  }


  var my_rpc_module = function() {};
  my_rpc_module.CheckFirstStep = function() {
    console.log("CheckFirstStep here.");
    return 'true';
  }
  my_rpc_module.DoSecondStep = function(userid) {
    console.log("CheckSecondStep here for userid " +userid + ".");
    return 'finished';
  }

  var _this_user_id = "Mr Blobby";

  var secondCallback = new Deferred();

  secondCallback.then(function(res) {
    console.debug('All is complete Result [' + res +']');
  });

  var firstCallback = new Deferred();
  firstCallback.then(function( res ) {
    if(res == 'true') {
        my_lib.processRPC( my_rpc_module.DoSecondStep( _this_user_id ), secondCallback );
    }
  });


  my_lib.processRPC( my_rpc_module.CheckFirstStep(), firstCallback );

})
于 2012-06-27T10:22:18.907 に答える
0

my.lib.processRPC処理のためにPromiseを返す必要があります。「Deferred」は、promise を拒否/履行するためのインターフェイスです。おそらく、これらのメソッドをエクスポートしたくないでしょう。コールバックをインストールできるプライベート スコープの Deferred から Promise を返すだけです。

私は Dojo の専門家ではありません。次のコードを正確な構文に適合させる必要があるかもしれません。あなたのシナリオに近い実装-my.rpc.module.DoSecondStep( _this.user_id )オプションオブジェクトを作成する関数のみであることを期待しています-は次のようになります。

my.lib.processRPC = function(options)
    var d = new Deferred();
    // ...
    return d.getPromise();
    // do some heavy and/or asynchronous processing and call
    d.resolve(result) // somewhen in the future
};

// narrative code:
my.lib.processRPC( my.rpc.module.getFirstStep() ).then(function(result) {
    if (result)
        return my.lib.processRPC( my.rpc.module.getSecondStep( _this.user_id ) )
          .then( function( res ) {
            console.debug('All is complete Result [' + res +']');
          });
     else
        return /* false */ result;
}).addCallback(console.log.bind(console, "everything finished"));

doStepXしかし、関数自体が実際に処理を行うべきであることをお勧めします。そのため、Deferreds/Promises を (最終的にはprocessRPC内部的に呼び出して) 返し、成功しなかった場合は拒否する必要があります。Deferred は、そのようなエラーを「バブル」します。

my.rpc.module.doFirstStep = function() {
    var d = new Deferred();
    // ...
    return d.getPromise();
    // do some heavy and/or asynchronous processing and call
    d.resolve(result) // or
    d.reject(error) // somewhen in the future
};
my.rpc.module.doSecondStep = function(id) {
    // returning a Promise, as above
};

// really narrative code:
my.rpc.module.doFirstStep()
  .then(my.rpc.module.doSecondStep)
  .addCallbacks(function( res ) {
    console.log('All is complete Result [' + res +']');
  }, function (err) {
    console.log('Something happened: [' + err +']');
  });

doSecondStep最初の deferred の (成功) 結果を引数として受け取ることに注意してください。それを望まない場合、または呼び出しなしで追加のパラメーターを指定する必要がある場合は、次のようなもの.bind()またはラッパー関数を使用する必要があります。

...then(function firstCallback() {
    return my.rpc.module.DoSecondStep( _this.user_id );
})...
于 2012-06-27T18:45:13.817 に答える