将上下文添加到无上下文的Java回调

问题描述 投票:2回答:2

我正在使用具有某些长时间运行功能的第三方JavaScript库(它涉及通过网络进行的Web服务调用等)。为简单起见,假设它需要一个参数,即长时间运行的操作完成时要调用的回调函数,因此,我们假设具有签名longRunningFunction(callback)

不幸的是,该函数不接受“上下文”参数,因此,如果我多次调用longRunningFunction,则在调用回调时,我无法知道哪个调用导致了哪个回调。

我发现了以下方法,可以通过使用匿名函数来解决此问题:定义mycallback(context)函数,然后每次调用长时间运行的操作都执行类似的操作:

uniqueContext = getUniqueContextFromSomewhere();
longRunningFunction(function() {mycallback(uniqueContext)});

似乎可以工作,但是我的问题是,考虑到长时间运行的操作可能在不同的条件下执行,是否在所有可能的情况下都可以根据JavaScript规范进行[[保证线程,对longRunningFunction的各种调用的回调可能以任何顺序出现,等等。那么,我发现的解决方案有效吗?

javascript callback dom-events
2个回答
2
投票
假设此代码:

function longRunningFunction( fn ) { window.setTimeout( fn, 1000 ); // just to make it async } function myCallback( context ) { /* ... */ }

现在,如果您有这个:

var uniqueContext = getUniqueContext( ); longRunningFunction( function ( ) { myCallback( uniqueContext ); } );

由标准指定,contextmyCallback参数将为uniqueContext 

在触发回调的那一刻。当您在循环中尝试类似的操作时,可能会导致一些问题(因为您将在每次迭代中擦除uniqueContext)。

如果您这样做:

var uniqueContext1 = getUniqueContext1( ); longRunningFunction( function ( ) { myCallback( uniqueContext1 ); } ); var uniqueContext2 = getUniqueContext2( ); longRunningFunction( function ( ) { myCallback( uniqueContext2 ); } );

第一个uniqueContext1结束时,将保证使用longRunningFunction的回调,而第二个uniqueContext2结束时,将使用longRunningFunction的回调(具有与以前相同的限制;如果覆盖[C0 ]或uniqueContext1在您范围内的某个位置,回调参数也会更改)。

使用绑定使您避免创建闭包(以及前面提到的默认设置)。以下代码与上一个代码相似,不同之处在于,您将永远无法通过覆盖上一个代码来意外更改参数的值:

uniqueContext2

[longRunningFunction( mycallback.bind( null, getUniqueContext1( ) ) );
longRunningFunction( mycallback.bind( null, getUniqueContext2( ) ) );
将返回一个函数,该函数将在调用时以mycallback.bind( null, someParameter )作为mycallback调用null(它将像任何常规函数一样回退到this),并以window作为第一个参数。

另一个答案仅使用someParameter的第一个参数,因为它们使用bind变量,但这不是必需的,您可以放心地使用函数参数。


2
投票
您可以使用this提供其他上下文。 Function.prototype.bind(thisArg [, arg1 [, arg2, …]])返回一个新方法,该方法在被调用时将其bind关键字设置为this。您的情况:

thisArg

这不适用于较旧的浏览器(例如,IE小于9),但是您可以使用polyfill或longRunningFunction(mycallback.bind(uniqueContext));
之类的库。要了解有关Underscore.js的更多信息,我推荐以下资源:

© www.soinside.com 2019 - 2024. All rights reserved.