Javascript 延迟链接,Node.js和q,一个用于所有链部件的错误处理程序
我有一个这样的设计:Javascript 延迟链接,Node.js和q,一个用于所有链部件的错误处理程序,javascript,node.js,promise,q,deferred,Javascript,Node.js,Promise,Q,Deferred,我有一个这样的设计: var postCommand = function(req, res){ parseForm(req) .then(checkData) .then(findCommand) .then(initializeCommand) .then(saveToDb) .then(onUploadSucceeded.bind(this, res)) .fail(onUploadFailed.bind(this, re
var postCommand = function(req, res){
parseForm(req)
.then(checkData)
.then(findCommand)
.then(initializeCommand)
.then(saveToDb)
.then(onUploadSucceeded.bind(this, res))
.fail(onUploadFailed.bind(this, res));
}
then中的方法可能会拒绝。我希望在拒绝发生后,除了最后一次。失败之外,不会再执行任何操作
我的“checkData”如下所示(是的,它是链中唯一的同步部分):
即使在调用deferred.reject时,我也会在“findCommand”中结束,而不传递参数。我理解这个链条有什么问题吗
还有一个问题:这种设计是一种好的模式吗?还是有其他/更好的最佳实践?正如Keith在其评论中所建议的,这是一个语法问题,解决方案:
var checkData = function(args){
var deferred = q.defer();
var fields = args[0];
var files = args[1];
var file = args[1].uploadedFile0;
var secondFile = args[1].uploadedFile1;
if(file.type !== "application/javascript"){
deferred.reject("please only upload javascript-files");
}
else{
deferred.resolve([fields, file]);
}
return deferred.promise;
}
正如Keith在评论中指出的,这是一个语法问题,解决方案:
var checkData = function(args){
var deferred = q.defer();
var fields = args[0];
var files = args[1];
var file = args[1].uploadedFile0;
var secondFile = args[1].uploadedFile1;
if(file.type !== "application/javascript"){
deferred.reject("please only upload javascript-files");
}
else{
deferred.resolve([fields, file]);
}
return deferred.promise;
}
如果checkData()
位于承诺链的开头,则需要像在中一样编写它,返回一个明确的承诺
在中链中,当这样写的时候它也会工作,但是中链在写什么上给了你更好的选择
更具体地说,您可以通过以下方式避免创建和返回承诺:
- 扔掉而不是退回被拒绝的承诺
- 返回数据而不是承诺包装的数据
checkData()
来启动承诺链,则可以这样编写:
var checkData = function(args) {
var fields = args[0],
files = args[1],
file = args[1].uploadedFile0,
secondFile = args[1].uploadedFile1;
if(file.type !== "application/javascript") {
throw new Error("please only upload javascript-files"); // always throw an Error object, thus emulating a natural Error. This error will percolate down to the `.fail(onUploadFailed.bind(this, res))` handler.
}
(...)
return [fields, file]; // the next step in the chain will assimilate a promise or data.
}
如果checkData()
位于承诺链的开头,则需要像在中一样编写它,返回一个明确的承诺
在中链中,当这样写的时候它也会工作,但是中链在写什么上给了你更好的选择
更具体地说,您可以通过以下方式避免创建和返回承诺:
- 扔掉而不是退回被拒绝的承诺
- 返回数据而不是承诺包装的数据
checkData()
来启动承诺链,则可以这样编写:
var checkData = function(args) {
var fields = args[0],
files = args[1],
file = args[1].uploadedFile0,
secondFile = args[1].uploadedFile1;
if(file.type !== "application/javascript") {
throw new Error("please only upload javascript-files"); // always throw an Error object, thus emulating a natural Error. This error will percolate down to the `.fail(onUploadFailed.bind(this, res))` handler.
}
(...)
return [fields, file]; // the next step in the chain will assimilate a promise or data.
}
您真的应该在每个
声明中进行响应验证,然后(…)
声明您的承诺。如果响应不包含预期的内容,那么您就破坏了承诺链。但是每个失败回调都会这样做。。。调用“onUploadFailed”,并将错误传递给拒绝。在我看来,这就像代码复制,降低了可读性。我想抛出一个exeption,而不是拒绝,因为q文档中说“catch”方法捕获上述链中的任何错误。但这似乎有点臭,我用蓝鸟,所以我不确定,但我认为你应该推迟返回。承诺在所有情况下。这是有效的!我不知道我为什么不试一下。谢谢你(见下面我的答案),我相信在为时已晚之前应该避免问。如果不是承诺,那么什么是延迟的。解决(42)返回?您应该在每个承诺声明中进行响应验证,然后(…)
声明。如果响应不包含预期的内容,那么您就破坏了承诺链。但是每个失败回调都会这样做。。。调用“onUploadFailed”,并将错误传递给拒绝。在我看来,这就像代码复制,降低了可读性。我想抛出一个exeption,而不是拒绝,因为q文档中说“catch”方法捕获上述链中的任何错误。但这似乎有点臭,我用蓝鸟,所以我不确定,但我认为你应该推迟返回。承诺在所有情况下。这是有效的!我不知道我为什么不试一下。谢谢你(见下面我的答案),我相信在为时已晚之前应该避免问。如果不是一个承诺,deferred.resolve(42)
将返回什么?鉴于函数是同步的,您根本不应该使用deferreds。使用Q
/Q.reject
创建已履行/拒绝的承诺,或者只使用return
和throw
,当checkData
用作then
处理程序时具有相同的效果。鉴于函数是同步的,您根本不应该使用延迟。使用Q
/Q.reject
创建已履行/已拒绝的承诺,或者只使用返回
和抛出
,这与检查数据
用作然后
处理程序时具有相同的效果。