2016-08-12 3 views
1

私のコードでは、3つのネストされたAJAX呼び出しを持つ関数があり、それを動作させるためにはAsync=falseを設定しなければなりませんでした。ネストされたAJAX呼び出しのJavaScriptの約束が機能していない

私はAsync=falseが非難されていると読んだので、Async=falsepromisesに置き換えました。

これは私がそれを編集した前に、私の関数である。

self.getOrders = function (name) { 
    var orders= []; 
    var order= function (item, type1, type2) { 
     var self = this; 
     self.order= item; 
     self.type1= type1; 
     self.type2= type2; 
    } 

$.ajax({ 
    url: "/API/orders/" + name, 
    type: "GET", 
    async: false, 
    success: function (orderResults) { 
     var mappedOrders = $.map(orderResults, function (orderItem) { 
     $.ajax({ 
      url: "/API/orders/property/" + orderItem.id + "/type1", 
      type: "GET", 
      async: false, 
      success: function (property1Results) { 
       $.ajax({ 
        url: "/API/orders/property/" + orderItem.id + "/type2", 
        type: "GET", 
        async: false, 
        success: function (property2Results) { 
          orders.push(new order(orderItem, property1Results, property2Results)); 
         } 
        }); 
        } 
       }); 
      }) 
     } 
    }); 
    return orders; 

この機能は完全に働いた、私はデータは、すべてがうまく働い終了しました。

//The begin of the function- same as first one 
var orders= []; 
var firstPromise = $.ajax({ 
     url: "/API/orders/" + name, 
     type: "GET" 
    }); 
    $.when(firstPromise).done(function (orderResults) { 
     var mappedOrders = $.map(orderResults, function (orderItem) { 
      var secondPromise = $.ajax({ 
       url: "/API/orders/property/" + orderItem.id + "/type1", 
       type: "GET" 
      }); 
      $.when(secondPromise).done(function (property1Results) { 
       var thirdPromise = $.ajax({ 
        url: "/API/orders/property/" + orderItem.id + "/type2", 
        type: "GET" 
       }); 
       $.when(thirdPromise).done(function (property2Results) { 
        orders.push(new order(orderItem, property1Results, property2Results)); 
       }); 
      }); 
     }); 
    }); 
    return orders; 

と関数呼び出し:

self.populateOrders = function (name) { 
    var mappedOrders = $.map(self.service.getOrders(name), function (item) { 
     return new Order(item) 
     }); 
    self.orders(mappedOrders); 
} 

新機能

それから私は、これはpromisesで、編集した機能です 、promises代わりのAsync=falseを使用するように機能を変更しましたは動作していません、私はfirstPromiseバックスラッシュと間違ったjsonから戻ってきて、返されたordersオブジェクトは空です。

私は間違って何を考えていますか?私はそれに多くの時間を費やしましたが、それを理解できませんでした。

ありがとうございます。

+0

残りの機能は共有してください(必要に応じて関連性の低いコードは削除してください)。 orders配列の代わりに約束を返し、その約束の 'resolve callback'の中でorders配列にアクセスする必要があります。 – Ozan

+0

私は自分の質問を編集しました。 – user3378165

+1

ネストされた約束事では、ネストされた約束事を返さなければなりません。 secondPromiseとthirdPromiseを宣言するのではなく、それを返します。 –

答えて

0

ネストされたAJAXコール管理するための地獄です。あなたはこのようにすることができます。

  • 全体のプロセスが終了すると、すべての内部のAJAX用
  • 待ちは、発信者に通知するためのあなたの主の約束

 

  • 解決を解決するために呼び出して、発信者に通知する約束を作成します。例で
    self.getOrders = function (name) { 
        var mainDeferred = $.Deferred(); 
        var orders = []; 
        var order = function (item, type1, type2) { 
         var self = this; 
         self.order = item; 
         self.type1 = type1; 
         self.type2 = type2; 
        } 
    
        $.ajax({ 
         url: "/API/orders/" + name, 
         type: "GET", 
         success: function (orderResults) { 
          var innerwait = []; 
    
          var mappedOrders = $.map(orderResults, function (orderItem) { 
           var ajax1 = $.ajax({ 
            url: "/API/orders/property/" + orderItem.id + "/type1", 
            type: "GET" 
           }); 
           var ajax2 = $.ajax({ 
            url: "/API/orders/property/" + orderItem.id + "/type2", 
            type: "GET" 
           }); 
           $.when(ajax1, ajax2).done(function (property1Results, property2Results) { 
            orders.push(new order(orderItem, property1Results[0], property2Results[0]))) 
           }); 
           innerwait.push(ajax1, ajax2); 
          });; 
    
          $.when.apply(null, innerwait) //make sure to wait for all ajax requests to finish 
           .done(function() { 
            mainDeferred.resolve(orders); //now that we are sure the orders array is filled, we can resolve mainDeferred with orders array 
           }); 
         } 
        }); 
    
        return mainDeferred.promise(); 
    } 
    
    
    self.populateOrders = function (name) { 
        self.service.getOrders(name).done(function (orders) { //use .done() method to wait for the .getOrders() to resolve 
         var mappedOrders = $.map(orders, function (item) { 
          return new Order(item) 
         }); 
         self.orders(mappedOrders); 
        }); 
    } 
    

    、IはWに$.when.apply()を使用することに注意してください繰延の配列のためのait。

  • +0

    これはうまくいくはずですが、jsfiddleでこれをテストできなかったことに注意してください。問題がある場合は、それらをjsfiddleで包んでください。それを修正する方法がわかります。 – Ozan

    +0

    @ Bergiのコメントは、あなたのAjax内部のAjax呼び出しを入れ子にする必要がないことを認識させました。これはコードをいくらか簡略化して、それに応じて編集しました。 – Ozan

    +0

    あなたの明確な答えをありがとう、私は今それを試し、あなたに知らせる、ありがとう! – user3378165

    -4

    クロム52(2016年8月)に最近導入されたバグは、この種の動作を引き起こす可能性があります。ネストされた要求に対する回答は無視されます。 うまくいけば、それは長く続くことはありません。

    https://bugs.chromium.org/p/chromium/issues/detail?id=633696

    キャッシュを追加しよう:偽ループ内

    関連する問題