为什么我不能设置 Dojo Deferred 的属性,如 dojo.store.JsonRest?



为什么我不能将延迟对象的(自定义用户定义(属性设置为同一延迟对象返回的承诺?我认为这是可能的,因为dojo.store.JsonRest做到了:

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(( 期望的格式。如果我将该承诺分配给我的延迟对象的属性,则会导致undefined 。但是,如果我将承诺分配给常规变量,则赋值有效。遗憾的是,查询结果需要分配属性。

我想我已经把问题归结为xhr()xhr().then()回报的承诺之间的差异。请检查此 jsFiddle 的控制台输出。

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

无法更改属性的直接原因是promise对象被冻结:

也就是说,防止向其添加新属性;防止删除现有属性

;并防止更改现有属性或其可枚举性、可配置性或可写性。从本质上讲,对象实际上是不可变的。

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

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

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

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/。

最新更新