0

为什么我不能将 Deferred 对象的(自定义用户定义的)属性设置为同一个 Deferred 对象返回的承诺?我认为这是可能的,因为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() 期望的格式。如果我将该承诺分配给我的 Deferred 对象的属性,它会导致undefined. 但是,如果我将承诺分配给常规变量,则分配有效。不幸的是,QueryResults 需要分配属性。

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

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

4

1 回答 1

2

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

也就是说,防止向其中添加新属性;防止现有属性被删除;并防止更改现有属性或其可枚举性、可配置性或可写性。本质上,对象实际上是不可变的

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

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

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

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

实际上,promise 的Deferredis stored 是 Deferred 的属性Deferred.promise,它也是被冻结的,Deferred.then()只是链接到Deferred.promise.then().

我不会推荐它,但如果你坚持改变promise你可以通过lang.delegate()

my_deferred = lang.delegate(my_deferred);

我稍微修改了您的 jsFiddle 以澄清上述内容:http: //jsfiddle.net/phusick/N3J7M/

于 2012-04-27T22:42:36.490 回答