【问题标题】:Async request in library which support AMD支持 AMD 的库中的异步请求
【发布时间】:2018-06-08 05:12:10
【问题描述】:

由于我使用 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);
});

我该如何解决这个问题?

【问题讨论】:

    标签: javascript asynchronous xmlhttprequest requirejs amd


    【解决方案1】:

    我相信你很快就发现你的第一次尝试是行不通的,因为你不能使用同步的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));
    });
    

    【讨论】:

      猜你喜欢
      • 2013-10-17
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 2012-10-11
      • 2015-11-26
      • 1970-01-01
      • 2016-11-26
      • 1970-01-01
      相关资源
      最近更新 更多