我正在构建一个使用异步资源的库。我希望库可以加载AMD / require。
我从2011年开始看到有关承诺支持的this discussion,但它无处可去。 我看过像async和require-promise这样的插件 - 但我不知道我对安装插件的库感觉如何。
我有兴趣知道在加载资源和/或依赖脚本方面是否有任何变化。如果不支持promises,是否有另一种方法可以通过异步方式告知requirejs脚本是否已准备就绪?
答案 0 :(得分:0)
我潜入了require.js的源代码,我没有找到一种方法来进行异步定义。插件具有此功能,但简单的定义则没有。我认为背后的原因是异步循环依赖有点棘手。
然而,编写一个迷你异步需求库并非不可能:
(function(context) {
const modules = new Map();
function require(name) {
return Promise.resolve(null).then(function() {
const module = modules.get(name);
if (!module) throw new Error("Undefined module");
if (module.promise) {
return module.exports;
} else {
return module.promise = Promise.all(
module.deps.map(internalRequire)
).then(function(args) {
return module.factory.apply(context, args);
}).then(function(defExport) {
if (defExport !== undefined) {
module.exports.default = defExport;
}
return module.exports;
});
}
function internalRequire(name) {
return (name === 'exports') ? module.exports : require(name);
}
});
}
function define(name, deps, factory) {
if (modules.has(name)) throw new Error("Redefined module");
modules.set(name, {
name: name,
deps: deps,
factory: factory,
exports: {},
promise: null
});
}
context.require = require;
context.define = define;
})(self);
用法:
define('A', ['B'], function(dep) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve("A(" + dep.default + ")");
}, 100);
});
});
define('B', ['C'], function(dep) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve("B(" + dep.default + ")");
}, 100);
});
});
define('C', ['A'], function(dep) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve("C(" + dep.default + ")");
}, 100);
});
});
require("A").then(function(s) {
console.log(s);
});