(JSメモ)IE用にXmlHttpRequestを用いた、async/await・Promise未使用の順序保証複数GET/POST用関数


作るに至った経緯は以下の記事に纏めています。

IEなどにおけるXMLHttpRequestで、複数リクエストをawaitするPromise.all的な処理を行いたい。

本体

function REQUEST_ALL(c, p) {
    var r = p.map(function(u) {
        var x = new XMLHttpRequest;
        x.addEventListener('loadend', function() {
            r.length == 1 + (p++) && c(r.map(function(v) {
                return {
                    url: v.responseURL,
                    status: v.status,
                    data: {
                        text: v.responseText || null,
                        json: (function(t) {
                            try {
                                return JSON.parse(t)
                            } catch (z) {
                                return null
                            }
                        }
                        )(v.responseText)
                    }
                }
            }))
        }),
        x.open(u.type, u.path, true, u.user, u.password),
        x.send(u.type !== 'GET' ? (function(y) {
            var f = new FormData;
            Object.keys(y).forEach(function(k) {
                Array.isArray(y[k]) ? y[k].forEach(function(v) {
                    f.append(k + '[]', String(v))
                }) : f.append(k, String(y[k]))
            });
            return f
        }
        )(u.param || {}) : null);
        return x
    })
      , p = 0
}

縮小版

function REQUEST_ALL(c,p){var r=p.map(function(u){var x=new XMLHttpRequest;x.addEventListener('loadend',function(){r.length==1+(p++)&&c(r.map(function(v){return{url:v.responseURL,status:v.status,data:{text:v.responseText||null,json:(function(t){try{return JSON.parse(t)}catch(z){return null}})(v.responseText)}}}))}),x.open(u.type,u.path,!0,u.user,u.password),x.send(u.type!=='GET'?(function(y){var f=new FormData;Object.keys(y).forEach(function(k){Array.isArray(y[k])?y[k].forEach(function(v){f.append(k+'[]',String(v))}):f.append(k,String(y[k]))});return f})(u.param||{}):null);return x}),p=0}

使い方

第一引数がコールバック関数、第二引数がリクエスト情報の配列です。

REQUEST_ALL(function(a) {
    console.log(a);
}, [
    {type: 'GET', path: 'a.json'},
    {type: 'GET', path: 'b.json', user: 'guest_user', password: 'guest_credential'},
    {type: 'POST', path: 'x.php', param: {a: 1, b: [1, 2, 3]}}
])

なお、コールバック関数の返り値は以下のようになっています。

[{...}, {...}, {...}]

↓↓↓

[
    {
        data: {
            text: "<responseText>",
            json: {...}// responseTextがJSONでパースできないならnull
        },
        status: 200,//400系などの時も
        url: "http://<...>/a.json"
    },
    {...},
    {...}
]