为什么我不能将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的控制台输出。
有什么区别,我该如何解决?
答案 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/。