2016-10-29 5 views
2

多くのリモートリソースがロードされ、最終的なコールバックを実行します(これらの要求から取得データに基づいてDOMをレンダリングする場合など)。最終的なコールバック、信頼できない注文を伴う多くのリクエスト?

はここで機能だ:

var ResourceLoader = function() { 

    this.requests = new Array(); 
    this.FinalCallback; 

    this.Add = function (request) { 
     this.requests.push(request); 
    }; 

    this.Execute = function() { 

     for (var x = 0; x < this.requests.length ; x++) { 

      var success = this.requests[x].success; 

      //if this is the last of the requests... 
      if (x == (this.requests.length - 1) && this.FinalCallback) { 

       $.when($.ajax({ 
          url: this.requests[x].url, 
          dataType: 'json', 
          error: this.requests[x].error, 
          method: 'GET' 
         }).done(success)).then(this.FinalCallback); 
      } 
      else { 

       $.ajax({ 
        url: this.requests[x].url, 
        dataType: 'json', 
        error: this.requests[x].error, 
        method: 'GET' 
       }).done(success);     
      } 

     } 

    }; 
}; 

そして、ここで私はそれを使用する方法は次のとおりです。

var apiUrl = Utilities.Api.GetWebApiUrl(); 
var loader = new Utilities.ResourceLoader(); 

loader.Add({ 
    url: apiUrl + 'regions/get', 
    success: function (results) { 
     Filters.Regions = results; 
    } 
}); 

loader.Add({ 
    url: apiUrl + 'currentfactors/get/83167', 
    success: function (results) { 
     Filters.NbrEmployees = results; 
    } 
}); 

loader.Add({ 
    url: apiUrl + 'currentfactors/get/83095', 
    success: function (results) { 
     Filters.Industries = results; 
    } 
}); 


loader.FinalCallback = RenderBody; 
loader.Execute(); 

function RenderBody() { 
    console.log('render...'); 
} 

を明らかに、私はRenderBodyが最後に実行されることを期待しています。しかし、それは起こっていることではありません。皮肉なのは前にそのようなことをやったことを覚えているのですが、コードを失ってしまったのです...私は脳の部分を持っているようです。

+0

は '私が最後に実行されるようにRenderBody期待していたときのjQueryを使用してを使用して、本当にきれいな解決策です' - 問題は、あなたが指摘したような非同期要求は順番に発生しないので、要求が最後のものかどうかを調べるのではなく、*応答*が最後のものかどうかを確認する必要があります –

+0

HTTPリクエストが終了すると終了します。保証された注文はありません。自分のカウンタを保持し、 "成功"コールバックでそれをインクリメントして、最後の応答をいつ処理するかを知ることができます。 – Pointy

+0

@Pointy 'ResourceLoader'では、提供された成功コールバックにカウンタチェックを注入する必要がありますか?私は 'ResourceLoader'がこれを処理します。 –

答えて

2

- ここPromise.all

this.Execute = function() { 
    Promise.all(this.requests.map(function(request) { 
    return $.ajax({ 
     url: request.url, 
     dataType: 'json', 
     error: request.error, 
     method: 'GET' 
    }).done(request.success); 
    })).then(this.FinalCallback); 
}; 

か...

this.Execute = function() { 
    $.when.apply($, this.requests.map(function(request) { 
    return $.ajax({ 
     url: request.url, 
     dataType: 'json', 
     error: request.error, 
     method: 'GET' 
    }).done(request.success); 
    })).then(this.FinalCallback); 
}; 
+0

まだ試してみませんでしたか?最新のブラウザとの互換性はどうですか? (IE、Edge、Chromeなど)? –

+0

Promise polyfillを使用しないIEはありません([OK polyfill]へのリンクは[MDN promise page](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise#See_alsoを参照) (https://github.com/jakearchibald/es6-promise/)...またはおそらく[bluebird](http://bluebirdjs.com/docs/getting-started.html)を使用してください。しかし、私は 'jquery.when'の代わりに更新しました - IEに問題を与えてはいけません –

+0

ありがとう、完璧に動作します。私は今のところjQueryの代替手段に固執します。 –

0

Es6 Promiseには、リソースグループのロードが特定の目的で抽象化されていない限り、問題を解決する必要はありません。各リソース要求に対してPromiseオブジェクトを設定し、コンストラクタを使用してXHRの解決コールバックと拒否コールバックを適切に割り当てます。コレクションはの結果(Iterableになります)を保ちます。最終製品はPromise.all(collectionOfPromises).then(finalCallback)です。あなたはタグが付いてきたように

関連する問題