如何在顶层等待javascript中的异步函数?
我知道这是个糟糕的主意。但是我有一个API,在我有一段只能异步获取的数据之前,我不能使用它。大概是这样的:如何在顶层等待javascript中的异步函数?,javascript,async-await,Javascript,Async Await,我知道这是个糟糕的主意。但是我有一个API,在我有一段只能异步获取的数据之前,我不能使用它。大概是这样的: const key = await get_async_data(config) // NOT RIGHT, can't use await at top level const api = new API(key) ... use api ... 这是在顶层,在任何函数之外,所以我不能只等待get\u async\u data()(它确实返回一个承诺)。 除了把我所有的代码放在一个巨大
const key = await get_async_data(config) // NOT RIGHT, can't use await at top level
const api = new API(key)
... use api ...
这是在顶层,在任何函数之外,所以我不能只等待get\u async\u data()(它确实返回一个承诺)。
除了把我所有的代码放在一个巨大的异步函数中以便调用wait,还有什么不足吗
API
只是一个由模块导出的类(由我控制)
(顺便说一句,我想把代码放到API
类的构造函数中,但是构造函数当然也不能是异步的。)
如果未设置,我可以让API
的每个异步方法都设置密钥,但这非常具有侵入性,而且容易出错
因此,我不是在问如何让顶层代码等待,而是在寻找其他方法来构造它,以便异步调用干净地进行
这里有一些更详细的情况,以防这有所帮助。
在api.js中:
class API {
constructor(key) {
this.key = key
// other stuff
}
async f1(a) {
}
async f2(b, c) {
}
f3() {
return true
}
}
export default API
然后在将使用它的地方(许多):
import API from '@/api'
const key = async get_key() // NOPE
const theAPI = new API(key)
async importantMethod(args)
{
return await theAPI.f1(args)
}
async otherMethod()
{
if (theAPI.f3)
return await theAPI.f2(123)
// etc...
}
// ... and so on
顶层是个糟糕的主意,是的。但我不明白为什么你不能把它放在函数里
const getAsync = async () => {
const key = await get_async_data(config);
return key;
}
getAsync().then(key => {
const api = new API(key)
}
只要用承诺:
const pendingAPI = get_async_data(config).then(key => new API(key)); // N.B. no await
export default pendingAPI;
同时,在另一个文件中
import pendingAPI from 'other/file';
pendingAPI.then(doStuffWithAPI);
有时
async/await
是一种胜利。但是别忘了,这只是对承诺的糖。 如果你想尽可能少地改变你现有的代码,我会考虑将入口点更改为获取密钥的模块,然后调用实例化API(旧的入口点)的模块。例如:
// start.js
import makeApi from './makeApi';
get_key()
.then(makeApi);
// makeApi.js
export default function(key) {
const theApi = new API(key);
function importantMethod(args) {
return theAPI.f1(args)
}
function otherMethod() {
if (theAPI.f3)
return theAPI.f2(123)
}
// etc
}
简而言之,您所要做的就是将当前入口点包装到函数中。您能解释一下将代码包装到
异步
函数中(或仅使用。然后)时遇到的问题吗?这似乎是一个显而易见的解决方案,我想在我所有的类中的任何地方都使用这个API。我不能把所有的东西都封装在一个巨大的异步函数中。我不确定你的意思,但是你需要在任何地方等待这个函数,你需要等待承诺的解决,然后才能继续。或者,如果你不想把所有的东西都用异步函数来包装,那就用use吧。那么你能用更多的代码给出一个更具体的例子吗,这样我们就可以看到什么东西看起来太乱了?还不太清楚的是,ATM必须调用api,将产生的承诺填充到var中,然后根据需要等待。如果使用,则不需要等待/异步。然后,只需执行获取异步数据(配置)。然后(key=>
同样,这也不是一个“糟糕的想法”(这不是一个坏主意,目前有一个顶级wait
的提案)这是一个目前规范不允许的想法。当然,但他似乎想在其他地方使用一个更小的函数。可能涉及其他参数?而且无论它是纯承诺还是写为async await都不在这里或那里。如果是建议,我不知道,很有趣。我仍然会说在gl中做任何功能obal通常是要避免的,但我知道在这方面还有其他POV。我想顶级await会让它感觉更像PHP/Python-y。幸运的是,项目中的顶级并不一定意味着全局性——这就是模块捆绑包的用途。