不止一次阻止绑定一个函数
我有一个recursion重试例程,如下所示:
Foo.prototype.retry = function(data, cb){ cb && (cb = cb.bind(this)); // want to bind the cb fn just once this.resolutions[x] = (err, val) => { if(val === 'foobar'){ // in this case, we do a retry return this.retry(data, cb); } }: }
正如你所看到的,在某些情况下,我会再次调用this.run
重试。 但是我想避免cb.bind()
调用cb.bind()
。 有没有什么好的方法来做到这一点?
=>我的意思是,有没有办法以某种方式检查一个函数是否绑定到某个this
值?
我所知道的唯一好的解决scheme是通过一个重试计数,如下所示:
Foo.prototype.retry = function(data, cb){ if(cb){ if(!data.__retryCount){ cb = cb.bind(this); } } this.resolutions[x] = (err, val) => { if(val === 'foobar'){ // we do a retry here data.__retryCount = data.__retryCount || 0; data.__retryCount++; return this.retry(data, cb); } }: }
你可以使用局部variables作为绑定版本,所以当你recursion调用自己的时候,你传递原始的cb
,而不是绑定的:
Foo.prototype.run = function(data, cb){ let callback = (cb && cb.bind(this)) || function() {}; this.resolutions[x] = (err, val) => { if(val === 'foobar'){ // we do a retry here and pass original cb return this.run(data, cb); } }; // then elsewhere in this function when you want to use the bound one, use callback() }
或者,如果你真的只想绑定一次,那么你可以在一个包装函数中做到这一点,并通过一个假设callback已经绑定的子函数recursion地调用自己:
// internal function, assumes callback is already bound Foo.prototype._run = function(data, cb){ // cb is already bound here this.resolutions[x] = (err, val) => { if(val === 'foobar'){ // we do a retry here return this._run(data, cb); } } } // bind the callback and then call our internal function Foo.prototype.run = function(data, cb){ let callback = (cb && cb.bind(this)) || function() {}; return this._run(data, callback); }
您可以创build一个类variables来指示函数是否被绑定:
let Foo = function() { this.resolutions = []; }; Foo.prototype.run = function(data, cb) { if (!this.bound) { console.log('binding'); cb && (cb = cb.bind(this)); this.bound = true; } this.resolutions[x] = (err, val) => { if (val === 'foobar') { // we do a retry here return this.run(data, cb); } }; }; console.log('x'); let x = new Foo(); x.run(); console.log('y'); let y = new Foo(); y.run(); console.log('x'); x.run();
由于绑定会遮盖Function.toString()方法中的原始纯文本函数源代码,因此您可以检查string版本以查看是否绑定了用户界面函数:
if(!/\[native code\]/.test(cb)) cb = cb.bind(this);
请注意,您不能在console.log
或window.alert
等原生方法上使用此方法,但这对您的使用情况可能不是问题。
总的来说:
Foo.prototype.retry = function(data, cb){ if(!/\[native code\]/.test(cb)) cb = cb.bind(this); // bind the cb fn just once this.resolutions[x] = (err, val) => { if(val === 'foobar'){ // in this case, we do a retry return this.retry(data, cb); } } };