延迟链接,Node.js和q,所有链部分的单个ErrorHandler

时间:2016-09-30 13:51:29

标签: 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, res));  
}

当时的方法可能会拒绝。我希望在拒绝发生后不再执行任何操作,但最后一次.fail。

我的" checkData"看起来像这样(是链中唯一的同步部分):

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"){
        return deferred.reject("please only upload javascript-files");
    }
    (...)
    return deferred.resolve([fields, file]);
}

即使调用了deferred.reject,我也会在" findCommand"没有参数传递。我理解这个链条有什么问题吗?

还有一个问题:这个设计是一个好的模式吗?或者还有其他/更好的最佳做法吗?

2 个答案:

答案 0 :(得分:2)

如果checkData()位于承诺链的开头,那么就需要像own answer一样写出来,然后返回明确的承诺。

在中间链中,它也可以像这样编写,但是中链可以为你提供更好的选择。

更具体地说,您可以通过以下方式避免创建和返回承诺:

  • 投掷而不是返回被拒绝的承诺,
  • 返回数据而非承诺包装数据。

因此,提供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. 
}

答案 1 :(得分:0)

正如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;
}