Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/439.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
向无上下文Javascript回调添加上下文_Javascript_Callback_Dom Events - Fatal编程技术网

向无上下文Javascript回调添加上下文

向无上下文Javascript回调添加上下文,javascript,callback,dom-events,Javascript,Callback,Dom Events,我正在使用一个第三方JavaScript库,它具有某种长期运行的功能(它涉及通过网络进行的web服务调用等)。为简单起见,假设它需要一个参数,即在长时间运行的操作完成时调用一个回调函数,因此假设我们有签名longRunningFunction(callback) 不幸的是,该函数不接受“context”参数,因此如果我多次调用longRunningFunction,当调用回调时,我无法知道哪个调用导致了哪个回调 我通过使用匿名函数找到了以下解决方法:定义mycallback(context)函数

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

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

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

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

这似乎是可行的,但我的问题是,在所有可能的情况下,这是否能保证在JavaScript规范下正常工作,因为长时间运行的操作可能在不同的线程上执行,对longRunningFunction的各种调用的回调可能以任何顺序出现,等等,我找到的解决方案有效吗?

您可以使用
Function.prototype.bind(thisArg[,arg1[,arg2,…])提供另一个上下文。
bind
返回一个新方法,该方法在调用时将其
this
关键字设置为
thisArg
。就你而言:

longRunningFunction(mycallback.bind(uniqueContext));
这在较旧的浏览器中不起作用(例如,小于9),但您可以使用polyfill或类似于library的浏览器。要了解有关绑定的更多信息,请参阅以下资源:


您可以使用
Function.prototype.bind(thisArg[,arg1[,arg2,…])提供另一个上下文。
bind
返回一个新方法,该方法在调用时将其
this
关键字设置为
thisArg
。就你而言:

longRunningFunction(mycallback.bind(uniqueContext));
这在较旧的浏览器中不起作用(例如,小于9),但您可以使用polyfill或类似于library的浏览器。要了解有关绑定的更多信息,请参阅以下资源:

假设此代码:

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

function myCallback( context ) {
    /* ... */
}
现在如果你有这个:

var uniqueContext = getUniqueContext( );
longRunningFunction( function ( ) { myCallback( uniqueContext ); } );
标准规定,
myCallback
context
参数将在触发回调时为
uniqueContext
。当您在循环中尝试类似的操作时,它可能会导致一些问题(因为您将在每次迭代中删除
uniqueContext

如果您这样做:

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

var uniqueContext2 = getUniqueContext2( );
longRunningFunction( function ( ) { myCallback( uniqueContext2 ); } );
使用
uniqueContext1
的回调保证在第一个
longRunningFunction
结束时调用,而使用
uniqueContext2
的回调保证在第二个
longRunningFunction
结束时调用(使用与以前相同的限制;如果覆盖范围中的某个位置的
uniqueContext1
uniqueContext2
,回调参数也将更改)

使用bind可以避免创建闭包(以及前面提到的默认值)。以下代码与前面的代码类似,只是您永远无法通过覆盖前面的代码来意外更改参数的值:

longRunningFunction( mycallback.bind( null, getUniqueContext1( ) ) );
longRunningFunction( mycallback.bind( null, getUniqueContext2( ) ) );
mycallback.bind(null,someParameter)
将返回一个函数,当调用该函数时,该函数将调用
mycallback
,并将
null
作为
(它将像任何常规函数一样回退到
窗口
)和
someParameter
作为第一个参数

另一个答案是只使用
bind
的第一个参数,因为它们使用
这个
变量,但它不是必需的,您可以安全地使用函数参数来代替。

假设这个代码:

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

function myCallback( context ) {
    /* ... */
}
现在如果你有这个:

var uniqueContext = getUniqueContext( );
longRunningFunction( function ( ) { myCallback( uniqueContext ); } );
该标准规定,
myCallback
context
参数将在触发回调时为
uniqueContext
。在循环中尝试类似操作时可能会导致一些问题(因为每次迭代时都会擦除
uniqueContext

如果您这样做:

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

var uniqueContext2 = getUniqueContext2( );
longRunningFunction( function ( ) { myCallback( uniqueContext2 ); } );
使用
uniqueContext1
的回调保证在第一个
longRunningFunction
结束时调用,而使用
uniqueContext2
的回调保证在第二个
longRunningFunction
结束时调用(使用与以前相同的限制;如果覆盖范围中的某个位置的
uniqueContext1
uniqueContext2
,回调参数也将更改)

使用bind可以避免创建闭包(以及前面提到的默认值)。以下代码与前面的代码类似,只是您永远无法通过覆盖前面的代码来意外更改参数的值:

longRunningFunction( mycallback.bind( null, getUniqueContext1( ) ) );
longRunningFunction( mycallback.bind( null, getUniqueContext2( ) ) );
mycallback.bind(null,someParameter)
将返回一个函数,当调用该函数时,该函数将调用
mycallback
,并将
null
作为
(它将像任何常规函数一样回退到
窗口
)和
someParameter
作为第一个参数


另一个答案是只使用
bind
的第一个参数,因为它们使用
this
变量,但这不是必需的,您可以安全地使用函数参数来代替它。

您是在问clousures是如何工作的吗?您可能想要:。如果您使用下划线:,或者jQuery:我强烈反对将其作为一个变量关闭闭包问题的“完全重复”。对于一个不是JS专家的人来说,这里的讨论如何映射到这个问题的答案一点也不简单。我可能能找到答案,但不确定我是否能正确回答。另一方面,有很多JS开发人员(包括初学者)使用使用异步回调模式的第三方库,因此StackOverflow将受益于这个特定问题的明确答案