我知道这是一个糟糕的主意。但是我有一个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_async_data()(它确实返回一个Promise)。 除了将我所有的代码都放在一个巨大的异步函数中,我还可以调用await吗?
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
答案 0 :(得分:0)
顶层是一个可怕的想法,是的。但是我不明白为什么不能只将它放在函数中?
override
答案 1 :(得分:0)
只需使用Promise:
0x10
同时,在另一个文件中...
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);
是赢家。但永远不要忘记,这只是对承诺的糖。
答案 2 :(得分:0)
如果您想尽可能少地更改现有代码,我会考虑将入口点更改为获取密钥的模块,然后调用实例化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
}
简而言之,您要做的就是将当前入口点包装在一个函数中。