Javascript 如何确定要从块中调用的回调函数的范围?

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

我使用的是第三方API,当响应返回时,它需要一个名为
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
)是所有实例使用的单个计数器(与实际回调变量不同,它不必是全局的,只需对类通用)。