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

时间:2015-06-19 06:16:08

标签: javascript asynchronous requirejs

我正在尝试创建一个需要在初始化完成之前从URL获取数据的模块。我怀疑我遗漏了一些显而易见的东西,但是如果令人满意,那么在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);
})

3 个答案:

答案 0 :(得分:2)

<块引用>

这是一个 6 年前的问题,但我以前需要它,可能再次需要它。我将回答异步模块初始化的一般问题:

您需要一个异步加载器插件,例如在此处找到的 requirejs-promisehttps://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>

答案 1 :(得分:1)

您可以向您的加载模块添加承诺并返回承诺。

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

答案 2 :(得分:-1)

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

而不是将流程分为两个步骤,您只需根据AMD / RequireJS的精神定义所需的额外CSV数据作为依赖:

require(["./csvProcessor", "text!./url.csv"], function(CsvProcessor, csvDataString) {
  var data = Processor.process(csvDataString);
})

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