首页 > 解决方案 > 有没有办法异步初始化 Viewmodel (KnockoutJS)

问题描述

我想异步初始化一个 ViewModel。我不是指异步加载我管理的 ViewModel(参见下面的代码)。

ViewModel 将被异步加载一次。之后,我想根据提供给 ViewModel 的参数做一些异步操作。看起来在获得参数后,您必须同步返回 ViewModel,不支持承诺/回调系统。请看下面的代码:


const defaultLoader: KnockoutComponentTypes.Loader = {
  loadViewModel: function (name, templateConfig, callback) {

    //if there is a 'fromUrl' property
    if (templateConfig.fromUrl) {

      //use import to load the code 
      import(templateConfig.fromUrl)
        .then(module => {

          //viewmodel is loaded asynchronous (one time!)
          callback( (params, componentInfo) => {
            
            //initialize the viewModel
            const model = module.default(
              params,
              componentInfo)
          
              //I can only return synchronously here:
            return model
          });
        })
    } 
  }
}

我想做的是使用 async/await 来表示它必须在一切解决之前等待:

          //ViewModel is loaded asynchronous (one time!)
          callback(async (params, componentInfo) => {

            //initialize the viewModel
            const model = module.default(
              params,
              componentInfo)

            //I can only return synchronously here:
            return await model
          });

但后来我的 ViewModel 最终成为了承诺对象。关于如何实现这一目标的任何建议?

标签: javascriptasynchronousknockout.jscomponentsknockout-3.0

解决方案


您不能从异步函数返回任何内容,但这与 Knockout 无关。你可以返回一个 promise,或者在你的 async 函数中调用其他函数。

为此,您应该能够在完成处理后使用 KO 的默认加载器(不要覆盖它,就像您现在正在做的那样)来创建视图模型,如下所示:

const customLoader: KnockoutComponentTypes.Loader = {
    loadViewModel: function(name, templateConfig, callback) {

        //if there is a 'fromUrl' property
        if (templateConfig.fromUrl) {

            //use import to load the code 
            import(templateConfig.fromUrl)
                .then(module => {

                    //viewmodel is loaded asynchronous (one time!)
                    callback((params, componentInfo) => {

                        //initialize the viewModel
                        const model = module.default(
                            params,
                            componentInfo)

                        ko.components.defaultLoader.loadViewModel(name, model, callback);
                    });
                })
        }
    }
}

推荐阅读