2017-05-03 13 views
-1

jQueryを使用してPromisesの仕組みを理解しようとしています。足す - 私は期待どおりに動作しますjQuery Deferred/Promises

function test1() { 
     var deferred = $.Deferred() 
     setTimeout(function() { 
      deferred.resolve(1); 
      //deferred.reject(2); 
     }, 2000); 
     return deferred.promise(); 
    } 

    function test2() { 
     var deferred = $.Deferred() 
     setTimeout(function() { 
      deferred.resolve(2); 
      // deferred.reject(2); 
     }, 1000); 
     return deferred.promise(); 
    } 

    function doTest(){ 
     $.when(test1()).then(
      function (a) { 
       console.log('test1 finished', a) 
       return test2(); 
      }, 
      function (a) { 
       console.log('something failed in test1', a) 
      } 
     ).then(
      function (b) { 
       console.log("test2 finished", b); 
      }, 
      function (b) { 
       console.log("something failed in test1", b); 
      } 
     ); 
    }  

test1の1

TEST2が

2を終え終えしかし、私は以下のようにそれを変更したとき が、これは私のサンドボックスです:

 function test1() { 
     var deferred = $.Deferred() 
     setTimeout(function() { 
      // deferred.resolve(1); 
      deferred.reject(2); 
     }, 2000); 
     return deferred.promise(); 
    } 

    function test2() { 
     var deferred = $.Deferred() 
     setTimeout(function() { 
      deferred.resolve(2); 
      // deferred.reject(2); 
     }, 1000); 
     return deferred.promise(); 
    } 

それはコンソールに書き込み:

何かがTEST2も実行されていないので、事実ではないものを未定義

終了test1の2

TEST2に失敗しました。

"test2 finished undefined"は表示しないでください。

私は何か間違っていると思いますが、何ですか?

+0

エラーハンドラでも 'test2'を呼び出す必要があります。あるいは、' test2 finished' -logging結果ハンドラを 'test2()'約束だけにインストールする必要があります。その前にエラーをキャッチします。 – Bergi

+0

jQuery 1.x/2.xのDeferreds/Promisesについて学んだことがあり、現在は3.xを使用していますが、動作が異なります。 3.xでは、キャッチハンドラ( '.then()'の2番目の引数)がデフォルトでキャッチします - エラーがスローされたり再スローされたり、(最終的に)拒否されたという約束が返されない限り、 。 –

答えて

0

あなたの問題は実際には最初のthenのonRejected関数にあります。具体的には、「値を返す」ため(定義されていない)、チェーン内の次のthenハンドラは、が達成されたとしてこれを処理します。約束します。

$.when(test1()).then(
     function (a) { 
      console.log('test1 finished', a) 
      return test2(); 
     }, 
     function (a) { 
      console.log('something failed in test1', a) 
      // Your problem is here. 
     } 
    ).then(
     function (b) { 
      console.log("test2 finished", b); 
     }, 
     function (b) { 
      console.log("something failed in test1", b); 
     } 
    ); 

これは、いくつかのケースで役立つことができます:

try { 
    a = test1(); 
    b = test2(); 
} catch (e) { 
    console.log('something failed in test1', a) 
} 
console.log("test2 finished", b); // this runs even if test1 or test2 fails, 
            // but in those cases b is undefined! 

代わりに、あなたはエラーハンドラを削除する必要があります。

$.when(riskyFunction()).then(
    function (value) { 
    return processValue(value); 
    }, function (error) { 
    console.log(error); 
    return defaultValue;   // This lets you recover... 
    }).then(function (value2) { 
    return processValue2(value2); // so this handler runs regardless of 
            // riskyFunction's return value. 
    }); 

同期コードと比較すると、これは狭いtryブロックに一致します最後にエラーをキャッチするか、return $.reject(a)またはthrow a以上でエラーチェーンを守り続けてください。thenハンドラ。

関連する問題