如何在 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>
我正在尝试创建一个需要在初始化完成之前从 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>