延迟解决始终在尝试捕获范围内
Deferred resolution always within try catch
我正在使用jQuery Deferred的独立实现(git repo)。保持问题简单,如果我进行var status = _.Deferred()
并从任何函数中返回status.promise()
,那么我是否必须为该函数中的所有步骤添加一个 try catch 以reject
延迟错误?
从返回 promise 的函数中抛出将在返回 promise 之前发生,因此,no:
function foo() {
var status = _.Deferred();
throw 'DOH!';
return status.promise(); // this will never execute
}
您遇到麻烦的地方是在 promise 返回函数中启动的异步调用是否可以抛出:
function bar() {
throw 'DOH!';
}
function foo() {
var status = _.Deferred();
setTimeout(function () {
status.resolve(bar());
}, 0);
return status.promise();
}
foo().
fail(function () {
// *not* invoked when bar throws
});
在这种情况下,您需要将调用包装为 bar
:
function bar() {
throw 'DOH!';
}
function foo() {
var status = _.Deferred();
setTimeout(function () {
try {
status.resolve(bar());
} catch (e) {
status.reject(e);
}
}, 0);
return status.promise();
}
foo().
fail(function () {
// invoked when bar throws
});
但是,接受回调的异步函数应捕获自己的错误,并将结果或错误传递给回调。
如果异步函数返回 promise,则不需要捕获,实际上也不需要创建自己的Deferred
:
function bar() {
var d = _.Deferred();
setTimeout(function () {
d.resolve(42);
}, 0);
return d.promise();
}
function foo() {
return bar().
then(function (result) {
return result * 2;
}).
then(function (result) {
if (result === 84) { // true
throw 'DOH!';
}
));
}
foo().
then(function (result) {
// *not* invoked
}).
fail(function (e) {
console.log(e.message); // 'DOH!'
});
在javascript中,try/catch不像Java那样是一种生活方式。原因是javascript在避免可预测类型的错误方面具有相当丰富的方法。
拒绝延期并非绝对必要。通常,如果需要执行某些fail
代码,或者需要主动防止以后解决延迟的某些事件,则会这样做。
人们很容易认为未解决/未被拒绝的延期将永远挂起。情况不一定如此。延迟可用于垃圾回收,此时在任何范围内都不存在对它的引用,无论是直接的还是通过其承诺。
人们也很容易认为已解决/拒绝的延迟会自动进行垃圾回收。这也是不真实的。如果对延迟的引用仍然存在,在任何范围内,那么它仍将存在于内存中,并且仍然有用,因为观察程序方法(例如 done/fail/always/then)可能会在以后被调用(并可能立即触发)。
简而言之,关于 GC,Deferreds 就像任何其他 js 对象一样,尽管通常使用它们的代码结构使得很难发现它们何时可用于 GC。
- Angularjs无法将单选按钮与嵌套范围内的模型绑定
- 如何使用D3生成特定范围内的随机颜色
- 将自定义css保持在角度范围内
- Angular JS-文本框未在独立范围内更新
- cookie不在网站范围内
- 获取给定JavaScript范围内的解析函数
- 如何在JavaScript中使用此函数对范围内的所有数字求和
- JavaScript-仅验证数值并且在范围内
- JS:从数组中查找特定范围内的最低/最高数字
- 试图检查表单中的值是否为一个设定范围内的数字
- 在十进制范围内搜索
- 基于日期范围的一组日期范围内的天数
- 如何在 Google 应用脚本中 sendEmail 函数的范围内的唯一非空白列中返回值
- 将数组传递给函数或确保它在范围内
- socket.io 客户端是否必须存在于全局范围内
- 查找某个日期范围内的可用天数
- 网站范围内jQuery/javascript选择器的最佳实践
- 如果指令包含在另一个指令中,我如何在隔离范围内添加双向数据绑定属性
- JS日期对象在某个范围内的百分比
- 延迟解决始终在尝试捕获范围内