2016-09-07 9 views
1

Phoenix Webアプリケーションからデータをダウンロードして、フロントエンドでデータをレンダリングしようとしています。このために、私はリスト内で要求とコールバックを持っており、それに対してリストを実行しています。それに対して、各リクエストはthenです。jQueryを使用した機能的約束

var Database = function() { 
    this.reservations = []; 
    this.applications = []; 
    this.environments = []; 
}; 

var database = new Database(); 

var requests = [$.getJSON('/api/applications', data => { database.applications = data }), 
       $.getJSON('/api/environments', data => { database.environments = data }), 
       $.getJSON('/api/reservations', data => { database.reservations = data })]; 

function run() { 
    requests.reduce(function(chain, callback) { 
     return (chain ? chain.then(callback) : callback); 
    }, null).then(() => render(database)); 
} 

ただし、これはほとんどの場合、Google Chromeの最新バージョンで動作し、おそらくSafariでは10%です。

レンダリング機能に入った後で「データベース」を調べると、アプリケーションの一覧は表示されますが、環境や予約(2つのデータ)は表示されません。

編集:これはGoogle Chromeの通常モードで動作します。しかし、シークレットモードでは常に動作しません。 Safariでは、3つすべてのデータを取得することがあり、場合によっては2つのデータしか取得しないこともあります。私のアプリケーションはセッションを使用しません。

私はこれが$ .ajaxの性質が非同期であり、私の約束を破ったことが原因であると推測しています。しかし、私はロードブロッキングを打った。

洞察?

答えて

1

あなたの約束を連鎖させる必要はありません。お互いに依存しているように見えないため、約束はすべて同時に要求することができます。代わりに、.map()を使用して、約束のリストとなる結果を取得し、.all()を使用してすべて解決するまで待つことができます。

(以下は擬似コード考慮されるべきであるので、私はいくつかの自由を取っている)

var urls = ['whatever.com', 'example.com/something', 'something.com/whatever']; 

var requestPromises = urls.map(function(url) { 
    return ajax(url); // assume ajax() returns a promise 
}); 

Promise.all(requestPromises).then(function(results) { 
    console.log(results); 
}); 
+0

だろうではない、あなただけの 'Promise.all(リクエスト).then(()=>レンダリング(データベース));' - すべて –

+0

のマップは必要ありません - 要求として見することは約束の配列でありますはい、あなたが正しい。私は '$ .getJSON()'呼び出しを見逃してしまい、リクエストを行うために使用されるデータオブジェクトだけであると考えました。 – Soviut

+0

私は問題を解決するための洞察を私に提供したので、これを答えとしてマークしましたが、ちょっと違う方法で修正しました。 @Soviut – hyde

1

あなたの助けのおかげ@Soviut。閉鎖のために:私はこの問題を解決するために何をしたのですか?

// ... is the ES6 spread operator 
function run() { 
    $.when(...requests).then(() => { 
    render(database); 
    }); 
} 
関連する問題