库中支持AMD

时间:2017-11-02 14:43:27

标签: javascript asynchronous xmlhttprequest requirejs amd

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

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

我确定您很快发现您的第一次尝试无法正常工作,因为您无法使用同步String uri = "http://localhost:7080/auth/realms/{RealmName}/protocol/openid-connect/token"; HttpClient client = HttpClientBuilder.create().build(); HttpPost post = new HttpPost(uri); post.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"); List<BasicNameValuePair> urlParameters = new ArrayList<BasicNameValuePair>(); urlParameters.add(new BasicNameValuePair("grant_type", "password")); urlParameters.add(new BasicNameValuePair("client_id", {ClientName})); urlParameters.add(new BasicNameValuePair("username", {UserName})); urlParameters.add(new BasicNameValuePair("password", {Password})); post.setEntity(new UrlEncodedFormEntity(urlParameters)); HttpResponse response = client.execute(post); System.out.println("Response Code : " + response.getStatusLine().getStatusCode()); BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuffer result = new StringBuffer(); String line1 = ""; while ((line1 = rd.readLine()) != null) { result.append(line1); } System.out.println(result); 来返回异步获取的值。

你的第二次尝试也无法奏效。看起来您希望传递给return的工厂函数以异步定义模块,但RequireJS不允许这样做。你需要做的是设计你的模块,它提供的功能允许模块的用户异步检索define的结果。

这是一些可能性的草图。我强调这是一个草图。我打了个袖口。至少,您需要添加错误处理代码:

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,
    };
});