And*_*pov 10 javascript node.js promise bluebird
短篇小说:
谈到Promises/A +,拒绝承诺的正确方法是什么 - 抛出错误?但如果我错过了catch- 我的整个应用程序将会爆炸!
如何使用promisify它有什么好处(也许你需要阅读更长的版本)?
是.then(success, fail)真正的反模式,我应该使用.then(success).catch(error)?
更长的版本,被描述为现实生活中的问题(希望有人阅读):
我有一个使用Bluebird(A + Promise实现库)的库,用于从数据库中获取数据(谈论Sequelize).每个查询都返回一个结果,但有时候它是空的(试图选择一些东西,但没有任何查询).承诺进入result函数,因为没有错误的原因(没有结果不是错误).例:
Entity.find(1).then(function(result) {
// always ending here, despite result is {}
}).catch(function(error) {
// never ends here
});
Run Code Online (Sandbox Code Playgroud)
我想包装它并检查结果是否为空(在我的代码中无法检查到这一点).我这样做了:
function findFirst() {
return Entity.find(1).then(function(result) {
if (result) { // add proper checks if needed
return result; // will invoke the success function
} else {
// I WANT TO INVOKE THE ERROR, HOW?! :)
}
}).catch(function(error) {
// never ends here
});
}
findFirst().then(function(result) {
// I HAVE a result
}).catch(function(error) {
// ERROR function - there's either sql error OR there is no result!
});
Run Code Online (Sandbox Code Playgroud)
如果你还在我身边 - 我希望你会明白这是什么.我想以某种方式启动错误功能(其中"ERROR功能").事情是 - 我不知道如何.我试过这些东西:
this.reject('reason'); // doesn't work, this is not a promise, Sequelize related
return new Error('reason'); // calls success function, with error argument
return false; // calls success function with false argument
throw new Error('reason'); // works, but if .catch is missing => BLOW!
Run Code Online (Sandbox Code Playgroud)
正如您可以通过我的评论(以及每个规范)看到的,抛出错误效果很好.但是,有一个很大但是 - 如果我错过了这个.catch陈述,我的整个应用程序都会爆炸.
为什么我不想要这个?假设我想在我的数据库中增加一个计数器.我不关心结果 - 我只是发出HTTP请求..所以我可以调用incrementInDB(),它有能力返回结果(即使出于测试原因),所以throw new Error如果它失败了.但既然我不关心回应,有时我不会添加.catch声明,对吧?但是现在 - 如果我不这样做(故意或故障) - 我最终会关闭你的节点应用程序.
我觉得这不太好.有没有更好的方法来解决它,或者我只需要处理它?
我的一个朋友帮助了我,我用了一个新的承诺解决问题,像这样:
function findFirst() {
var deferred = new Promise.pending(); // doesnt' matter if it's Bluebird or Q, just defer
Entity.find(1).then(function(result) {
if (result) { // add proper checks if needed
deferred.resolve(result);
} else {
deferred.reject('no result');
}
}).catch(function(error) {
deferred.reject('mysql error');
);
return deferred.promise; // return a promise, no matter of framework
}
Run Code Online (Sandbox Code Playgroud)
奇迹般有效!但我进入了这个:Promise Anti Patterns - 由Bluebird(A +实现)的创建者Petka Antonov撰写的维基文章.它明确地说这是错误的.
所以我的第二个问题是 - 是吗?如果是 - 为什么?什么是最好的方式?
非常感谢您阅读本,我希望有人会花时间来回答对我来说:)我要补充一点,我不想依赖于框架太多了,所以Sequelize和Bluebird只是事情,我结束了工作.我的问题是Promises作为一个全局,而不是这个特定的框架.
请每个帖子只询问一个问题:-)
是
.then(success, fail)真正的反模式,我应该使用.then(success).catch(error)?
不,他们只做不同的事情,但一旦你知道你可以选择合适的东西.
如何使用
promisify它有什么好处?
我认为Bluebird Promisification文档很好地解释了它 - 它用于将回调api转换为返回promises的api.
谈到Promises/A +,拒绝承诺的正确方法是什么 - 抛出错误?
是的,抛出错误是完全没问题的.在then回调中,您可以抛出并自动捕获它,从而导致拒绝结果承诺.
你也可以用; 两者都会有完全相同的效果.return Promise.reject(new Error(…));
我的一个朋友帮助了我,我用了一个新的承诺解决问题,像这样:[...]
不,你真的不应该使用它.只需then在那里使用并抛出或返回被拒绝的承诺.
但如果我错过了捕获声明 - 我的整个应用程序将会爆炸!
不,它不会.请注意,该.catch()方法不是一个try catch语句 - 在then调用回调的地方已经捕获了错误.然后它只catch作为参数传递给回调,.catch()不需要调用来捕获异常.
如果你错过了.catch(),你的应用程序将不会爆炸.所有会发生的事情是,您有一个被拒绝的承诺,您的应用程序的其余部分将不会受此影响.您将收到一个未处理的拒绝事件,可以在全球范围内处理.
当然,这不应该发生; 每个promise 链(不是每个promise 实例)都应以.catch()适当处理错误的方式结束.但是你肯定不需要.catch()在每个辅助函数中,当它向其他地方返回一个promise时,那么调用者通常会处理错误.
谈到Promises/A +,拒绝承诺的正确方法是什么 - 抛出错误?但如果我错过了捕获 - 我的整个应用程序将会爆炸!
如果您使用返回代码来表示错误而不是异常,那么错过检查将导致细微的错误和不稳定的行为.忘记处理错误是一个错误,但让你的应用程序在这样一个不幸的情况下爆炸通常比让它继续处于损坏状态更好.
调试忘记的错误代码检查只是由于应用程序在一些无关的错误源位置表现得很奇怪,很容易比调试一个被遗忘的捕获程序贵很多个数量级,因为你有错误消息,源代码错误和堆栈跟踪.因此,如果您希望在典型的应用程序开发方案中获得生产力,那么异常会以非常大
.then(成功,失败)
这通常表示您使用promises作为美化回调,其中回调只是单独传递.这显然是一种反模式,因为以这种方式使用promises不会带来任何好处.如果情况并非如此,那么即使这样,您使用的代码与使用相比也会略微降低.catch(),类似于method(true, true, false)可读性低得多method({option1: true, option2: true, option3: false}).
如何使用promisify以及它有什么好处(也许你需要阅读更长的版本)?
大多数模块只公开一个回调接口,promisify将一个回调接口自动转换为一个promise接口.如果您手动编写此类代码(使用延迟或new Promise),则会浪费您的时间.
所以我的第二个问题是 - 是吗?如果是 - 为什么?什么是最好的方式?
最好的方法是实现承诺:
function findFirst() {
return Entity.find(1).tap(function(result) {
if (!result) throw new Error("no result");
});
}
Run Code Online (Sandbox Code Playgroud)
它更好,因为它更简单,更短,更易读,并且更不容易出错的方式做同样的事情.
| 归档时间: |
|
| 查看次数: |
8685 次 |
| 最近记录: |