

抛开具体细节不谈,一个普通 Vue 组件从创建到展现在页面里,主要经历了以下流程:
// 组件 Object
{
 template: '<div>I am async!</div>'
}
// 经过 compileToFunctions 得到对应的 render function 
with(this) {
 return _c('div', [_v("I am async!")])
}
// 在经过 render 得到 Vnode 再 update 成为真实DOM动态组件&异步组件与之有什么区别呢?
主要区别在于 render 中 createComponent 这一步,举例。
// 组件
Vue.component('example', {
 template: '<div>I am async!</div>'
})普通组件在 createComponent 时,会依据开发者自定义的 options,利用 Vue.extend 生成对应的构造函数,从而得到对应的 Vnode 。而一个异步组件
// 异步组件
Vue.component('async-example', function (resolve, reject) {
 // 利用 setTimeout 模拟请求
 setTimeout(function () {
 // 向 `resolve` 回调传递组件定义
 resolve({
 template: '<div>I am async!</div>'
 })
 }, 1000)
})则是要经过一系列处理,具体过程如下
在源码的 create-component。
// async component
let asyncFactory
if (isUndef(Ctor.cid)) {
 asyncFactory = Ctor
 Ctor = resolveAsyncComponent(asyncFactory, baseCtor, context)
 if (Ctor === undefined) {
 // return a placeholder node for async component, which is rendered
 // as a comment node but preserves all the raw information for the node.
 // the information will be used for async server-rendering and hydration.
 return createAsyncPlaceholder(
 asyncFactory,
 data,
 context,
 children,
 tag
 )
 }
}首先 Ctor 就与之前不同,这里为一个 function
function (resolve, reject) {
 // 利用 setTimeout 模拟请求
 setTimeout(function () {
 // 向 `resolve` 回调传递组件定义
 resolve({
 template: '<div>I am async!</div>'
 })
 }, 1000)
}之后调用 resolveAsyncComponent(asyncFactory, baseCtor, context)
resolveAsyncComponent 在源码的 resolveAsyncComponent。
resolveAsyncComponent 的主要功能是定义 Ctor 所需要的 resolve 、reject 函数
// factory 为 Ctor factory(resolve, reject)
以 resolve 函数为例
const resolve = once((res: Object | Class<Component>) => {
 // 缓存 resolved
 factory.resolved = ensureCtor(res, baseCtor)
 // 强制渲染
 if (!sync) {
 	forceRender(true)
 }
})once 字面理解,就是只调用一次。当 Ctor 中 setTimeout 结束时调用。
ensureCtor 就是 Vue.extend 的封装以适应不同场景,所以 resolve 函数的主要功能就是在异步完成时,将得到的 Ctor 转化为构造函数,缓存在 factory.resolved 中。
之后利用 forceRender(true) 强制重新 render,由于之前缓存了 factory.resolved,resolveAsyncComponent 函数就直接返回了组件的构造函数。
if (isDef(factory.resolved)) {
 return factory.resolved
}之后就与普通组件一致了。
总结
