0

jQuery 3.0.0 を使用すると、

$(function() {

  var n = 5;

  function jQueryWhenApplyResolveRejectWith(n) {
    
    var arr = $.map(Array(5), function(_, i) {
      return $.Deferred();
    });

    var obj = {
      "index": null
    };

    var promises = $.when.apply(null, arr.map(function(promise, i) {
      return i < n 
             ? promise.resolveWith(obj, [i]) 
             : promise.rejectWith((obj.index = i, obj)
               , [new Error(i + " is not less than " + n)])
    }));
    
    function success(...result) {
      console.log("resolved, result:", result, "this:", this);
    }
    
    function err(error) {
      console.log("rejected, error:", error, "this:", this);
    }
    
    return promises.then(success, err);
    
  }
  
  jQueryWhenApplyResolveRejectWith(n)
  .then($.proxy(jQueryWhenApplyResolveRejectWith, null, --n))

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js">
</script>

への最初の呼び出しは、 にチェーンされたjQueryWhenApplyResolveRejectWith解決済みの jQuery promise 値の配列を返す必要があります。ここで、 はオブジェクトの配列です。.then()promisesthisobj

への 2 番目の呼び出しは、単一のオブジェクトに設定されたjQueryWhenApplyResolveRejectWithを返す必要があります。Errorthisobj

単一のオブジェクトが に渡されたため、 の予期される結果はsuccesssingleにthis設定されます。objdeferred.resolveWith

期待される結果は返されませんが、javascriptat stacksnippets では、.bind()または$.proxy()at.then()チェーンを使用して単一のオブジェクトを返すことができますpromises

$(function() {

  var n = 5;

  function jQueryWhenApplyResolveRejectWith(n) {
    
    var arr = $.map(Array(5), function(_, i) {
      return $.Deferred();
    });

    var obj = {
      "index": null
    };

    var promises = $.when.apply(null, arr.map(function(promise, i) {
      return i < n 
             ? promise.resolveWith(obj, [i]) 
             : promise.rejectWith((obj.index = i, obj)
               , [new Error(i + " is not less than " + n)])
    }));
    
    function success(...result) {
      console.log("resolved, result:", result, "this:", this);
    }
    
    function err(error) {
      console.log("rejected, error:", error, "this:", this);
    }
    
    return promises.then($.proxy(success, obj), err);
    
  }
  
  jQueryWhenApplyResolveRejectWith(n)
  .then($.proxy(jQueryWhenApplyResolveRejectWith, null, --n))

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js">
</script>

質問:

  1. thisに渡されたプレーン オブジェクトから配列に変換されるの はなぜですか.resolveWith()。に渡された同じオブジェクトは、パターン.rejectWith() を使用して単一のオブジェクトを返しますか?$.when.apply()

  2. $.when.apply()or .resolveWith()、または両方を同じ手順で使用した場合の予想される動作は、解決された jQuery promise オブジェクトの数を乗算したthis元を含む配列に設定されますか?this

4

1 に答える 1

0

jQuery.when と jQuery.Deferred.resolveWith で .apply() を使用して配列に変換されるのはなぜですか?

  1. これが .resolveWith(); に渡されたプレーン オブジェクトから配列に変換されるのはなぜですか。.rejectWith() に渡された同じオブジェクトは、$.when.apply() パターンを使用して単一のオブジェクトを返しますか?
  2. $.when.apply() または .resolveWith()、または両方を同じ手順で使用した場合の予想される動作は、元の this を含む配列に設定され、解決された jQuery promise オブジェクトの数を掛けたものですか?

各 promise オブジェクトには独自のコンテキストがあります。thisatsuccess関数として返される配列は、this解決された各 promise の値を表します。promise が解決または拒否される間でコンテキストが変更される可能性があるため、thisは単一のオブジェクトまたは返された配列内の単一の値にフラット化されませんが、最初に に渡された jQuery promise オブジェクトごとに異なります$.when.apply()

はい、これは予想される動作であると信じてください。$.when.apply()は jQuery メソッドではありませんが、promise の配列を に渡して$.when()解決済みの promise の配列を取得する方法.then()、または渡された配列内の promise のいずれかが拒否された場合は単一の拒否された promiseを取得する方法であることに注意してください。

解決された promise の配列が戻り値である場所でthis期待される結果が単一の場合、 orを使用してat関数に設定できます。success.bind()$.proxy()thissuccess

  return i < n 
         ? promise.resolve(i) // use `.resolve()` instead of `.resolveWith()` here
         : promise.rejectWith((obj.index = i, obj)
           , [new Error(i + " is not less than " + n)])

  return promises.then(success.bind(obj), err); // use `.bind()` to set `this`

err単一の拒否された promise のみがonRejectedハンドラーに返されるため、関数を調整する必要はありません。ここでthisは、配列ではなく単一の値になります。

于 2016-09-18T15:02:44.193 に答える