我有以下示例:
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
函数执行。
答案 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
构建执行流程并不是正确的做法。还存在性能问题。使用if
为less 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 */
}
}