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 承诺值数组,位于.then()chained to promises,其中this是一个obj对象数组。

第二次调用jQueryWhenApplyResolveRejectWith应该返回Error,并this设置为单个对象obj

的预期结果success设置this为 single obj,因为单个对象被传递给deferred.resolveWith.

虽然没有返回预期的结果,但javascript在 stacksnippets 处,可以通过 using.bind()$.proxy()at .then()chained to返回单个对象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 或两者的预期行为是否设置为包含原始数组乘以已解析的 jQuery 承诺对象的数量?.resolveWith()thisthis

4

1 回答 1

0

为什么使用 .apply() 与 jQuery.when 和 jQuery.Deferred.resolveWith 将其转换为数组?

  1. 为什么这会从传递给 .resolveWith() 的普通对象转换为数组;而传递给 .rejectWith() 的同一对象使用 $.when.apply() 模式返回单个对象?
  2. 在同一过程中使用 $.when.apply() 或 .resolveWith() 或两者的预期行为是否设置为包含原始 this 的数组乘以已解析的 jQuery 承诺对象的数量?

每个 Promise 对象都有自己的上下文。this作为atsuccess函数返回的数组表示this每个已解决的承诺的值。由于上下文可以在被解决或拒绝的承诺之间改变,因此this不会展平为单个对象或返回数组中的单个值,而是对于最初传递给的每个 jQuery 承诺对象都是不同的$.when.apply()

是的,相信这是预期的行为。请注意,这$.when.apply()不是 jQuery 方法,而是一种将一组承诺传递给$.when()并检索已解决承诺的数组的方法.then(),或者如果传递的数组中的任何一个承诺被拒绝,则单个被拒绝的承诺。

如果预期的结果是单一this的,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 回答