Reactjs 等待动态导入
我使用React和Typescript创建了一个web应用程序。它使用了一个相当沉重的第三方库。我想通过使用将其从主捆绑包中排除 因此,我没有从“库”导入{Component},而是创建了一个小包装器,如下所示:Reactjs 等待动态导入,reactjs,typescript,async-await,Reactjs,Typescript,Async Await,我使用React和Typescript创建了一个web应用程序。它使用了一个相当沉重的第三方库。我想通过使用将其从主捆绑包中排除 因此,我没有从“库”导入{Component},而是创建了一个小包装器,如下所示: const loadLibrary = async () => { const x = await import('library').then((r) => r); return x; }; const { Component, } = loadL
const loadLibrary = async () => {
const x = await import('library').then((r) => r);
return x;
};
const {
Component,
} = loadLibrary() as any;
// tslint:disable-next-line:no-console
console.log(`typeof Component is ${typeof Component}`);
export {
Component,
};
然后,在我的应用程序中,我将使用“../library wrapper.ts”导入{Component}。
由于包装器使用动态导入表达式,Webpack会创建一个单独的块,该块仅由浏览器下载,然后才是实际需要的块<代码>\o/
但坏消息是:我的包装器实际上并不等待动态导入表达式。它调用loadLibrary()
函数,但立即继续执行,并记录日志
组件的类型未定义
因此,当我尝试使用组件时,React崩溃:
元素类型无效:需要字符串(对于内置组件)或类/函数(对于复合组件),但得到:未定义
有什么建议吗?loadLibrary
是一个异步函数,因此它返回一个承诺而不是常规对象。因此,您必须执行wait loadLibrary()
或loadLibrary()。然后(…)
来获取库对象
这样做的结果是,您无法静态导出动态导入的内容,因为静态导入/导出是立即同步完成的,而动态导入是异步完成的。您只能导出函数loadLibrary
,并允许模块用户在需要库时调用该函数
简而言之,一次异步,永远异步;您不能强制在JavaScript中同步运行异步的东西
另外,您的loadLibrary
函数可以简化很多,只需
const loadLibrary = () => import('library');
因为a)。然后((r)=>r)
只创建了一个承诺的相同副本,b)在返回异步函数(它是自动完成的)之前不必等待,c)返回承诺的函数不必标记为异步
(尽管您仍然可以,如果您愿意,例如为了可读性).我认为的整个想法是,你实际上可以等待一个承诺
得到解决。在这种情况下我错了吗?是的,你是对的,但是你仍然必须使用wait
关键字来等待承诺(告诉JS这是你想要的承诺的结果,而不是承诺本身)。由于不能以同步方式运行异步代码(我认为这是由于JavaScript的单踏板设计),因此只能在标记为async
的函数中使用wait
,否则必须使用。然后(r=>{/*对结果做点什么*/})
。