如何退出函数 cascade/chain?
How do I exit a function cascade/chain?
如果您使用 return this
的函数创建一个对象,您可以创建之前调用的函数链并创建级联函数调用:
var i = {
foo: function () {
// Something here...
return this;
},
bar: function () {
// Something here...
return this;
}
};
i.foo().bar().foo()
但是,如果在 bar
中发生错误并且我不想在那种情况下调用 foo
怎么办?如何打破级联?
如果可能的话,我想避免 try/catch
语句。
也许不是您想要的,但 Promises 非常适合链接和错误处理:
var i = {
count: 0,
foo: function () {
// Something here...
this.count++;
console.log('foo');
return this.count < 4 ?
Promise.resolve(this) :
Promise.reject(new Error('Count too high!'));
},
bar: function () {
// Something here...
this.count++;
console.log('bar');
return this.count < 4 ?
Promise.resolve(this) :
Promise.reject(new Error('Count too high! Count is ' + this.count));
}
};
i.foo() // first
.then(i => i.bar()) // second
.then(i => i.foo()) // third
.then(i => i.bar()) // too much!
.then(i => i.whatIsThis()) // will not run
.then(i => i.whatIsThis()) // will not run
.catch(error => console.log(error.message));
可以 return 一个新的 i 的空实例,然后在错误 return 一个空对象时:
class Chainable {
constructor(data){
this.data = data;
}
foo (foo) {
//if an error occured
if(foo == 10) return new Chainable();
// Something here...
return new Chainable(this.data + foo);
},
bar () {
//if were in an error, fail silently
if(!this.data) return this;
// Something here...
return this;
}
}
(new Chainable(1))
.foo(5).bar().bar().data // 6
(new Chainable(1))
.foo(10).bar().bar().data //undefined
好吧,一件直截了当的事情是,如果你想在没有 try/catch
的情况下处理这种情况,你必须在你的函数中加入 if 条件,显然你必须 return一些东西,这样你就可以在那个上下文而不是异常上执行更多的功能。因此,尝试在一个对象中创建所有功能,并仅在有人扩展时才允许执行您的功能逻辑。失败时 return 基础,否则 return 当前对象。这样您就可以避免每次都创建对象。
示例:
让我们考虑一下您有 BaseService
定义了所有功能,并在其上放置一个层以进一步扩展,因此您可以采用这种模式:
foo: function() {
if(<function foo does not belongs to this>) {
.......
.......
if(<on logical failure>) {
return this.__proto__;
}
.......
.......
}
return this;
}
这是一个工作片段:
function BaseService() {
var dataBucket = [13, 50, 45, 57, 95];
this.foo = function() {
if (Object.values(this).indexOf(arguments.callee) === -1) {
console.log('processing foo');
}
return this;
}
this.bar = function() {
if (Object.values(this).indexOf(arguments.callee) === -1) {
console.log('processing bar');
}
return this;
}
this.processValIfExists = function(val) {
if (Object.values(this).indexOf(arguments.callee) === -1) {
console.log('processing processValIfExists');
if (dataBucket.indexOf(val) > -1) {
//process the value further
} else {
return this.__proto__;
}
}
return this;
}
};
//define the extended service, you can add further
//functionalities here. eg: createing the dataBucket here from args
function WrapperService() {};
WrapperService.prototype = new BaseService(); // just extend from any service and use
var svc = new WrapperService();
console.log('----------Executes All-----------');
svc.foo().bar().processValIfExists(95).foo().bar();
console.log('----------Executes upto processValIfExists-----------');
svc.foo().bar().processValIfExists(100).foo().bar();
请注意,这只是我想到的一种不同的方法,为了检查当前的调用方法,我尝试使代码通用,而不是检查它的 WrapperService
实例是否在 BaseService
函数以避免代码耦合,也可以从任何其他服务扩展。
如果您使用 return this
的函数创建一个对象,您可以创建之前调用的函数链并创建级联函数调用:
var i = {
foo: function () {
// Something here...
return this;
},
bar: function () {
// Something here...
return this;
}
};
i.foo().bar().foo()
但是,如果在 bar
中发生错误并且我不想在那种情况下调用 foo
怎么办?如何打破级联?
如果可能的话,我想避免 try/catch
语句。
也许不是您想要的,但 Promises 非常适合链接和错误处理:
var i = {
count: 0,
foo: function () {
// Something here...
this.count++;
console.log('foo');
return this.count < 4 ?
Promise.resolve(this) :
Promise.reject(new Error('Count too high!'));
},
bar: function () {
// Something here...
this.count++;
console.log('bar');
return this.count < 4 ?
Promise.resolve(this) :
Promise.reject(new Error('Count too high! Count is ' + this.count));
}
};
i.foo() // first
.then(i => i.bar()) // second
.then(i => i.foo()) // third
.then(i => i.bar()) // too much!
.then(i => i.whatIsThis()) // will not run
.then(i => i.whatIsThis()) // will not run
.catch(error => console.log(error.message));
可以 return 一个新的 i 的空实例,然后在错误 return 一个空对象时:
class Chainable {
constructor(data){
this.data = data;
}
foo (foo) {
//if an error occured
if(foo == 10) return new Chainable();
// Something here...
return new Chainable(this.data + foo);
},
bar () {
//if were in an error, fail silently
if(!this.data) return this;
// Something here...
return this;
}
}
(new Chainable(1))
.foo(5).bar().bar().data // 6
(new Chainable(1))
.foo(10).bar().bar().data //undefined
好吧,一件直截了当的事情是,如果你想在没有 try/catch
的情况下处理这种情况,你必须在你的函数中加入 if 条件,显然你必须 return一些东西,这样你就可以在那个上下文而不是异常上执行更多的功能。因此,尝试在一个对象中创建所有功能,并仅在有人扩展时才允许执行您的功能逻辑。失败时 return 基础,否则 return 当前对象。这样您就可以避免每次都创建对象。
示例:
让我们考虑一下您有 BaseService
定义了所有功能,并在其上放置一个层以进一步扩展,因此您可以采用这种模式:
foo: function() {
if(<function foo does not belongs to this>) {
.......
.......
if(<on logical failure>) {
return this.__proto__;
}
.......
.......
}
return this;
}
这是一个工作片段:
function BaseService() {
var dataBucket = [13, 50, 45, 57, 95];
this.foo = function() {
if (Object.values(this).indexOf(arguments.callee) === -1) {
console.log('processing foo');
}
return this;
}
this.bar = function() {
if (Object.values(this).indexOf(arguments.callee) === -1) {
console.log('processing bar');
}
return this;
}
this.processValIfExists = function(val) {
if (Object.values(this).indexOf(arguments.callee) === -1) {
console.log('processing processValIfExists');
if (dataBucket.indexOf(val) > -1) {
//process the value further
} else {
return this.__proto__;
}
}
return this;
}
};
//define the extended service, you can add further
//functionalities here. eg: createing the dataBucket here from args
function WrapperService() {};
WrapperService.prototype = new BaseService(); // just extend from any service and use
var svc = new WrapperService();
console.log('----------Executes All-----------');
svc.foo().bar().processValIfExists(95).foo().bar();
console.log('----------Executes upto processValIfExists-----------');
svc.foo().bar().processValIfExists(100).foo().bar();
请注意,这只是我想到的一种不同的方法,为了检查当前的调用方法,我尝试使代码通用,而不是检查它的 WrapperService
实例是否在 BaseService
函数以避免代码耦合,也可以从任何其他服务扩展。