Javascript 如何确定要从块中调用的回调函数的范围?
我使用的是第三方API,当响应返回时,它需要一个名为Javascript 如何确定要从块中调用的回调函数的范围?,javascript,typescript,scope,Javascript,Typescript,Scope,我使用的是第三方API,当响应返回时,它需要一个名为callback\u data(json)的回调函数 但是,它似乎在全局范围内调用callback\u data(json)。我想在一个块中定义callback\u data(json)函数的范围,以便通过promise控制流 以下是我的尝试: return new Promise(resolve => { (function(callback_data) { api.request
callback\u data(json)
的回调函数
但是,它似乎在全局范围内调用callback\u data(json)
。我想在一个块中定义callback\u data(json)
函数的范围,以便通过promise控制流
以下是我的尝试:
return new Promise(resolve => {
(function(callback_data) {
api.request({"q": term}); //The third-party API call
})(function(json) {
resolve({...json.data, q: term})
});
}
);
因此,行api.request({“q”:term})
在收到服务器的响应时将调用回调_数据(json)
函数。但它在全局范围内调用回调函数。我希望它从块内调用启动的api.request()
我所做的是,我认为我可以将所有内容放入一个自调用函数中,并将callback\u data(json)
函数作为参数传递到自调用函数中。我认为这将涵盖自调用函数块中的所有内容。不幸的是,这不起作用
我如何定义回调函数的作用域,它应该位于全局作用域,从块中调用
我在代码中使用的是Typescript。如果API的编码真的会导致以下问题:
callback_data(json);
…在无法添加函数的范围内,您无能为力。API设计得很糟糕(除非它是JSONP,在这种情况下,这是它唯一的工作方式,但它应该允许您指定函数名),并且callback\u data
必须是全局的
这并不意味着它必须是长寿的。您可以全局声明它:
var callback_data = null; // At global scope
…然后在代码中为其指定一个值,并在完成后清除该值:
return new Promise(resolve => {
callback_data = function() { // Assign
callback_data = null; // Clear on callback
resolve({...json.data,
q: term
});
};
api.request({"q": term});
});
如果它是JSONP,并且允许您在请求中指定回调名称,则更好,因为您可以为每个请求创建不同的回调名称:
// Using `window` as JSONP is by definition in a browser
window.lastCallbackId = 0;
return new Promise(resolve => {
++lastCallbackId;
var name = "myCallback" + lastCallbackId;
window[name] = function() { // Assign, will be "myCallback1", "myCallback2", ...
window[name] = null; // Clear on callback
resolve({...json.data,
q: term
});
};
api.request({
"q": term,
callbackName: name // Note passing the name to it
});
});
如果API的编码确实存在以下问题:
callback_data(json);
…在无法添加函数的范围内,您无能为力。API设计得很糟糕(除非它是JSONP,在这种情况下,这是它唯一的工作方式,但它应该允许您指定函数名),并且callback\u data
必须是全局的
这并不意味着它必须是长寿的。您可以全局声明它:
var callback_data = null; // At global scope
…然后在代码中为其指定一个值,并在完成后清除该值:
return new Promise(resolve => {
callback_data = function() { // Assign
callback_data = null; // Clear on callback
resolve({...json.data,
q: term
});
};
api.request({"q": term});
});
如果它是JSONP,并且允许您在请求中指定回调名称,则更好,因为您可以为每个请求创建不同的回调名称:
// Using `window` as JSONP is by definition in a browser
window.lastCallbackId = 0;
return new Promise(resolve => {
++lastCallbackId;
var name = "myCallback" + lastCallbackId;
window[name] = function() { // Assign, will be "myCallback1", "myCallback2", ...
window[name] = null; // Clear on callback
resolve({...json.data,
q: term
});
};
api.request({
"q": term,
callbackName: name // Note passing the name to it
});
});
这听起来像JSONP。它通过返回加载到新的
标记中的脚本来工作。它无法访问其他函数的本地名称,您必须将函数分配给全局名称。这听起来像JSONP。它通过返回加载到新的
标记中的脚本来工作。它无法访问其他函数的本地名称,您必须将函数分配给全局名称。谢谢您的回答。现在我对发生的事情有了更好的了解。因为我使用的是Typescript,而且我的所有东西都在一个类中,所以我尝试使用一个类变量作为private callback\u data:(json)=>void代码>然后我按照您在示例中所做的那样,将函数分配给this.callback\u data
。然而,类变量似乎不在全局范围内,并且不起作用。如果我已经在课堂上有了东西,我该怎么办?@Carven:在课堂上有东西并不能真正改变上述任何事情。您需要使回调全局化类实例方法中的此
不是全局的。与上面的第二个示例一样,您可能需要将其置于窗口中。另外,请确保您使用的计数器(lastCallbackId
)是所有实例使用的单个计数器(与实际回调变量不同,它不必是全局的,只是类通用的)。谢谢您的回答。现在我对发生的事情有了更好的了解。因为我使用的是Typescript,而且我的所有东西都在一个类中,所以我尝试使用一个类变量作为private callback\u data:(json)=>void代码>然后我按照您在示例中所做的那样,将函数分配给this.callback\u data
。然而,类变量似乎不在全局范围内,并且不起作用。如果我已经在课堂上有了东西,我该怎么办?@Carven:在课堂上有东西并不能真正改变上述任何事情。您需要使回调全局化类实例方法中的此
不是全局的。与上面的第二个示例一样,您可能需要将其置于窗口中。还要确保您使用的计数器(lastCallbackId
)是所有实例使用的单个计数器(与实际回调变量不同,它不必是全局的,只需对类通用)。