如何在 RequireJS 模块中进行异步初始化

How to do asynchronous initialization in a RequireJS module

我正在尝试创建一个需要在初始化完成之前从 URL 获取数据的模块。我怀疑我遗漏了一些明显的东西,但是如何让 RequireJS 等到我的异步调用完成后才能满足 require 调用。

// data module
(function() {
  Papaparse("http://url.csv", {
    complete: function(results) {
      /* need to return these results from this module after the async call */
    }
  });

  /* what do I return here? */
})

// main
require(["data"], function(d) {
  /* displays "undefined"  becase the async call is not complete yet */
  console.log(d);
})

您可以将 promise 添加到您的加载模块和 return promise 。

然后 main.js 需要业务逻辑来确定所有承诺完成后的完成 https://api.jquery.com/promise/

有一个专门用于此任务的官方插件:text

本着 AMD/RequireJS:

的精神,您只需将所需的额外 CSV 数据定义为依赖项,而不是将过程分为两个步骤
require(["./csvProcessor", "text!./url.csv"], function(CsvProcessor, csvDataString) {
  var data = Processor.process(csvDataString);
})

请注意,根据 the documentation,模块的 URL 仍受 XHR 限制的影响,因此数据文件需要托管在与您的应用相同的域中 运行 来自(除非使用 CORS 等)。

It's a 6 year old question, but I've needed it before, and may again. I'll answer the general question of asynchronous module initialization:

你需要一个异步加载器插件,例如 requirejs-promise 在这里找到:https://github.com/jokeyrhyme/requirejs-promise - 在这里转载,简要地说:

define('promise', function(){var g=function(b){return b&&"object"===typeof b?window.Promise&&b instanceof Promise?!0:"function"===typeof b.then:!1};return{load:function(b,h,c){h([b],function(a){var d=function(){c.error.apply(null,arguments)};var e=function(){c.apply(null,arguments)};if(g(a)){var f=a.done||a.then;"function"===typeof a.fail?(f.call(a,e),a.fail(d)):f.call(a,e,d)}else c(a)})}}});

这是一个使用它的简单示例(尽管您通常可能会通过 require 加载插件本身和异步模块):

<!DOCTYPE html>

<html>
  <body>
  </body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>
  <script>
    // Load requirejs-promise.js inline
    define('promise', function(){var g=function(b){return b&&"object"===typeof b?window.Promise&&b instanceof Promise?!0:"function"===typeof b.then:!1};return{load:function(b,h,c){h([b],function(a){var d=function(){c.error.apply(null,arguments)};var e=function(){c.apply(null,arguments)};if(g(a)){var f=a.done||a.then;"function"===typeof a.fail?(f.call(a,e),a.fail(d)):f.call(a,e,d)}else c(a)})}}});

    // An example async-loading module returning a promise (not
    // supported by vanilla requirejs)
    define('some-async-module', [], function() {
      return new Promise(function(res,rej) {
        setTimeout(function() {
          var module = { data:[1, 2, 3] };
          res(module);
        }, 2000);
      })
    });

    // Loading that module with promise! prefix
    document.body.innerHTML += 'Loading... 2 sec...<br>';
    require(['promise!some-async-module'], function(m) {
      document.body.innerHTML += 'Loaded async module: '+JSON.stringify(m);
    })
  </script>
</html>