Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 等待动态导入_Reactjs_Typescript_Async Await - Fatal编程技术网

Reactjs 等待动态导入

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

我使用React和Typescript创建了一个web应用程序。它使用了一个相当沉重的第三方库。我想通过使用将其从主捆绑包中排除

因此,我没有从“库”导入{Component},而是创建了一个小包装器,如下所示:

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=>{/*对结果做点什么*/})