为什么我不能像Dojo.store.JsonRest那样设置Dojo Deferred的属性?

时间:2012-04-27 07:00:15

标签: ajax dojo deferred

为什么我不能将Deferred对象的(自定义用户定义的)属性设置为同一个Deferred对象返回的promise?我认为这是可能的,因为dojo.store.JsonRest does it

var results = xhr("GET", {
    url: this.target + (query || ""),
    handleAs: "json",
    headers: headers
});
results.total = results.then(function(){
    var range = results.ioArgs.xhr.getResponseHeader("Content-Range");
    return range && (range=range.match(/\/(.*)/)) && +range[1];
});
return QueryResults(results);

我必须做一些非常相似的事情,但我链接一个额外的延迟对象,因为我需要将我的JSON输入转换为QueryResults()期望的格式。如果我将该承诺分配给我的Deferred对象的属性,则会生成undefined。但是,如果我将promise分配给常规变量,则赋值可以正常工作。不幸的是,QueryResults需要分配属性。

我认为我已经将问题归结为xhr()xhr().then()返回的承诺之间的差异。请检查this jsFiddle的控制台输出。

有什么区别,我该如何解决?

1 个答案:

答案 0 :(得分:2)

您无法更改属性的直接原因是promise对象is frozen

  

即阻止将新属性添加到其中;防止删除现有属性;并防止现有属性或其可枚举性,可配置性或可写性被更改。本质上使对象有效地不可变

Dojo文档解释了为什么承诺被冻结:

  

.then()调用返回一个新的promise,表示执行回调的结果。 回调永远不会影响原始承诺的价值。

您可以更改Deferred返回的xhr()属性的原因是

  

dojo.Deferred是一种promise ,它提供了通过成功结果或错误来履行承诺的方法。

实际上,存储Deferred的承诺是Deferred的属性Deferred.promise,该属性也被冻结,Deferred.then()只链接到Deferred.promise.then()

我不推荐它,但是如果你坚持要更改promise,你可以通过lang.delegate()来实现它:

my_deferred = lang.delegate(my_deferred);

我修改了你的jsFiddle以澄清前面提到的:http://jsfiddle.net/phusick/N3J7M/