从另一个函数停止执行函数

时间:2014-04-03 06:55:01

标签: javascript node.js

我有以下示例:

function foo1 (callback) {

    if (!foo2(callback)) {
        return;
    }

    console.log("Doing something");
    /* do something */
}

function foo2 (callback) {
    return callback ();
}

foo1 (function () {
     console.log ("Hello World!");
});

我想从if中移除foo1。我可以停止foo1执行调用foo2吗?我正在寻找这样的东西:

function foo1 (callback) {

    foo2(callback); // calling foo2 this way I want to prevent
                    // the console.log below to be executed

    console.log("Doing something");
    /* do something */
}

有没有办法做到这一点?

请注意,我不想抛出错误。我只想调用回调函数并停止函数执行。

用例

而不是:

 function a (options, callback) {

     callback = callback || function () {};
     if (typeof callback !== "function") {
         callback = function (err) { console.log (err); }
     }

     if (!options.someField || options.someField.constructor !==  Object) {
         return callback ("someField should be an object");
     }

     /* do something */
 }

我希望:

 function a (options, callback) {

     validateFunction (callback, callback);
     validateObject (options, callback);
     validateObject (options.somField, callback);

     /* do something */
 }

如果其中一个validate*函数失败,它应该通过callback发送错误并停止a函数执行。

4 个答案:

答案 0 :(得分:1)

有一种方法,请使用throw

function foo2(callback) {
    // do what you want to do
    throw true;
}

然后catching

try {
   foo1();
}
catch (e) {
   // if false, real error, 
}

但它出现在一个奇怪的设计中。我希望您有正当理由,并且对将来审核您的代码的其他人都很清楚。

答案 1 :(得分:1)

我会使用if语句:

function a (options, callback) {

    if (!validateFunction (callback)) return;
    if (!validateObject (options, callback)) return;
    if (!validateObject (options.somField, callback)) return;

    /* do something */
}

如果你总是从这样的场景中调用validateFunction函数,那么validate...函数不一定需要2个参数,boolean函数总是返回function validateObject (options, errorCallback) { if (!options.someField || options.someField.constructor !== Object) { errorCallback("someField should be an object"); return false; } return true; } ,其中包含验证和调用的结果发生错误时的回调。

try catch

正如许多纯粹主义者所说,使用try catch构建执行流程并不是正确的做法。还存在性能问题。使用ifless performant,然后是控制语句(例如try catch

尽管function a (options, callback) { try { validateFunction (callback); validateObject (options); validateObject (options.someField); catch (err) { callback(err); return; } /* do something */ } function validateObject (options, errorCallback) { if (!options.someField || options.someField.constructor !== Object) { throw "someField should be an object"; } } 版本更快且产生的代码更少但我仍然不喜欢它,因为它在代码中不太清楚:

{{1}}

答案 2 :(得分:1)

如果您可以使用promises

 function a (options) {
     return validateObject(options).then(function(){
         return validateObjecT(options.somField);
     }).then(function(){
          return validateObjecT2(options.somField);
     }).then(function(){
          return validateObjecT3(options.somField);
     }).then(function(){
          return validateObjecT4(options.somField);
     }).then(function(){
          /*do something*/
     });
 }

 var validateObject = Promise.method(function(object) {
      // Because this is inside Promise.method, thrown error
      // will be equal to return Promise.reject(new Error("invalid"));
      if (typeof object !== "object") throw new Error("invalid");
 });

或者,功能a也可以这样做:

function a (options) {
 // If any validation fails, the do something is skipped
 // and the code resumes at the next .catch() with the validation
 // error passed as parameter
 return Promise.all([
    validateObject(options),
    validateObject2(options),
    validateObject3(options),
    validateObject4(options),
    validateObject(options)
 ]).then(function(){
    /*do something*/
 })
}

 a({}).then(function() {
    // Validation succeeded and everything was done
 }).catch(function(e) {
    // Validation or something else failed, e is the rejection error
 });

请勿将字符串用作错误,string is not an error

也就是说,永远不要这样做:

throw "foo";
callback("foo");
reject("foo") // When using promises

取而代之的是:

throw new Error("foo");
callback(new Error("foo"));
reject(new Error("foo")) // When using promises

答案 3 :(得分:0)

为你的函数取一个布尔值

function foo1(callback, exe) {

    if (exe) {
        foo2(callback);
    } else {
        console.log("Doing something");
        /* do something */
    }
}