我是否应该改变一个已承诺并已解决的值的内部状态
Should I mutate internal state of a value that was promised and is already resolved?
代码示例(可变性)
.factory('objSingleton', function ($q) {
var o = {a: 1}
setTimeout(function () {
o.a = 2
}, 1000)
return $q.when(o)
})
另一种选择是(不变性)
.factory('objFactory', function ($q) {
var promise = $q.when({a: 1})
setTimeout(function () {
promise = $q.when({a: 2})
}, 1000)
return function () {
return promise
}
})
问题
我希望听到"赞成"answers"反对"的声音,以帮助我决定是接受承诺还是不接受承诺(在创建+返回承诺的API中)。
注意:代码示例使用AngularJS风格的依赖项注入器,但问题和答案适用于任何和所有使用promise的JS环境
承诺不应在做出此决定时发挥任何作用
毕竟,承诺只是对可能需要时间的计算的抽象。承诺的结果是对正常结果的抽象。
通常,具有不可变的值是一种很好的做法,因为可变状态无论如何都有是非常糟糕的。可变状态使测试更加困难。在您的情况下,可变全局状态甚至更糟。Angular的作者米斯科·哈维里写了一篇关于为什么的最好的文章,名为《单身汉是病态的骗子》。
所以,答案是——做同步代码中应该做的事情。您会在同步代码中返回一个副本或引用吗。这是一个我无法真正回答的主观问题,但所有事实都指向";在您的代码中具有尽可能少的状态";。
我非常不同意你的意见。该框架在这一决定中发挥着重要作用。在angular中,如果将解析值附加到一个或多个范围,然后更改解析值,则angular将自动更新所有相关视图。我认为这是angular的一个主要特征,所以我确实改变了我决心的promise值。
如果您返回一个新的promise,您需要自己$watch
值,并负责视图的任何更新。正因为如此,我不喜欢使用不可变的值。
在其他框架中,它可能不会以同样的方式工作,这个问题可能会有另一个答案。
Promise结果值肯定应该被认为是不可变的。
承诺确实促进了函数式编程风格,解决这些问题将永远解决它们的价值。他们的约定是,无论何时发生,他们都将调用具有完全相同值的所有回调。您不应该仅仅将其视为对象身份,还应该将其视为由对象"状态"。
不改变结果值将导致更干净、更不容易出错的代码 甚至还有promise库通过Object.freeze
对解析值进行强制执行
这种方法的唯一缺点是,对对象进行必要的克隆会慢得多。然而,如果您可以绝对确定除了您之外没有其他人使用这些值,则可以对对象进行变异。
在我个人看来,angular确实对此过于宽容,但这种突变的自动传播是他们的设计。
- 如何在状态输入ui路由器时立即显示模板,然后当承诺被解决时显示数据
- 处理角度.js承诺错误状态
- 表现出承诺'加载状态
- Javascript-承诺保留为挂起状态
- 将承诺置于待处理状态
- UI 路由器:是否可以解析子状态中的父承诺
- 如何使用Angular检索HTTP状态代码;s$q承诺
- 与承诺状态的角度绑定
- 承诺失败状态
- 当一个函数必须返回承诺时,我如何在一个状态中实现多个解析
- 当页面刷新或深链接时,Angular-ui-router无法实现状态解析的承诺
- Angular UI-Router——在resolve中返回被拒绝的承诺并不能停止状态转换
- 承诺解析哪些状态码
- 承诺数据在路由状态改变时不呈现
- 在承诺解析后修改组件状态
- 共享一个承诺(Redux状态)
- 我是否应该改变一个已承诺并已解决的值的内部状态
- 有没有一种方法可以检查$.when(..)中承诺的个人结果,而不管最终状态如何
- 什么原因导致“;错误:未捕获(承诺中):Url为null的状态为200的响应“”;出现
- 承诺后的角度状态变化