由于我用XMLHttpRequest发出的异步请求,我想构建一个库时遇到了问题。我将用一些代码来解释:
(function(root,factory){
if( typeof define === "function" && define.amd ){
// AMD module
define([], factory);
}else{
global.tof = factory();
}
})(this, () => {
const obj = {
datas: {},
get: function(){}
...
}
const url = "...";
let request = new XMLHttpRequest();
request.open('GET',url);
request.responseType = 'json';
request.send();
request.onload= function(){
obj.datas = request.response;
}
return obj;
});
我使用回调来确保在加载数据时接收数据并定义我的模块,但是当我使用requireJS加载“库”时,它仍然在真正定义我的模块之前触发。
(function(root,factory){
function myCallback(r){
if( typeof define === "function" && define.amd ){
// AMD module
define('tof',[], factory(function(r){
return r;
}));
}
}
factory(myCallback);
})(this, function foo(callback){
const obj = {
datas: {},
get: function(){}
...
}
const url = "...";
let request = new XMLHttpRequest();
request.open('GET',url);
request.responseType = 'json';
request.send();
request.onload= function(){
obj.datas = request.response;
callback(obj);
}
});
我用来用requireJS测试模块的另一个脚本:
require(['tof'], function(tof){
// return undefined because of my async request
console.log(tof);
});
我该如何解决这个问题呢?
发布于 2017-11-03 19:26:11
我相信您很快就会发现第一次尝试是行不通的,因为您不能使用同步return
来返回异步获取的值。
你的第二次尝试也不起作用。看起来您希望传递给define
的工厂函数异步定义模块,但RequireJS不允许这样做。您需要做的是设计模块,使其提供允许模块的用户异步检索XMLHTTPRequest
结果的函数。
以下是一些可能性的草图。我强调这只是一个草图。这是我即兴打出来的。至少,您需要添加错误处理代码:
define(function () {
const promise = new Promise((resolve, reject) => {
const request = new XMLHttpRequest();
request.open('GET',url);
request.responseType = 'json';
request.send();
request.onload = () => {
obj.datas = request.response;
resolve(obj);
};
});
return {
getResult: () => promise,
};
});
然后你可以在其他地方使用它,比如:
require(['tof'], function (tof) {
tof.getResult().then((result) => console.log(result));
});
https://stackoverflow.com/questions/47078056
复制相似问题