1

對於讀取下面顯示的表格腳本,我試圖在參數中運行查詢,並嘗試將每個結果的值從不同的表格追加到結果中。但由於azure的異步特性,request.respond()總是在getInvites之前調用。這意味着結果永遠不會附帶邀請。在Azure中處理多個異步請求?

function read(query, user, request) { 

    request.execute({ 
     success: function (results) { 
      for (var i = 0; i < results.length; i++) { 
       getInvites(results[i].id, function (invites) { 
        console.log("Assigning results.invites"); //runs second 
        results[i].invites = invites; 
       }); 
      } 
      console.log("Request Responding"); //runs first 
      request.respond(); 
     } 
    }); 

} 

function getInvites(id, cb) { 
    var InvitesTable = tables.getTable("Invites").where({ 
     "PlanID": id 
    }).select("UserID", "Attending"); 
    InvitesTable.read({ 
     success: function (results) { 
      if (cb) cb(results); 
     } 
    }); 
} 

這是一個this的後續問題,因爲我不能在Azure中使用外部庫。那麼我該如何解決這個問題呢?

+0

在這個框架中的任何自定義事件?或者你可以使用jQuery,或者有'.addEventListener()'方法可以從你的'getInvites'訪問一個對象。只要給我一個這些選項。 – kidwon

+0

沒有,可悲。這裏是一個參考http://msdn.microsoft.com/en-us/library/windowsazure/jj554226.aspx – user972616

回答

4

操作的異步性使得這有點具有挑戰性。你需要做的是隻有在完成所有操作後才致電request.respond()。我真的很想念我非常喜歡C#的await關鍵字,但我之前使用過「異步循環」,並且工作得很好。你的代碼看起來像下圖所示:

function read(query, user, request) { 
    request.execute({ 
     success: function (results) { 
      var index = 0; 
      var executeStep = function() { 
       if (index === results.length) { 
        // all invites have been retrieved 
        console.log("Request Responding"); 
        request.respond(); 
       } else { 
        getInvites(results[index].id, function(invites) { 
         console.log('Assigning results.invites'); 
         results[i].invites = invites; 
         index++; 
         executeStep(); 
        }); 
       } 
      } 

      executeStep(); 
     } 
    }); 
} 

function getInvites(id, cb) { 
    var InvitesTable = tables.getTable("Invites").where({ 
     "PlanID": id 
    }).select("UserID", "Attending"); 
    InvitesTable.read({ 
     success: function (results) { 
      if (cb) cb(results); 
     } 
    }); 
} 
+0

謝謝你作品完美:) – user972616

0

好吧,你可能會做這樣的事情

function read(query, user, request) { 

    request.execute({ 
     success: function (results) { 
      for (var i = 0, len = results.length; i < len; i++) { 
       getInvites(results.id, function (invites) { 
        console.log("Assigning results.invites"); //runs second 
        results.invites = invites; 

        if (i === len-1) request.respond(); 
       }); 
      } 
      console.log("Request Responding"); //runs first 
     } 
    }); 

} 

function getInvites(id, cb) { 
    var InvitesTable = tables.getTable("Invites").where({ 
     "PlanID": id 
    }).select("UserID", "Attending"); 
    InvitesTable.read({ 
     success: function (results) { 
      if (cb) cb(results); 
     } 
    }); 
} 

這基本上意味着,request.respond()將在您最後一次迭代的成功回調被調用。

+0

不起作用:(for循環在getInvites調用完成之前完成,所以request.respond()仍然先運行 – user972616

+1

由於'getInvites'中的所有操作都是異步的,因此不保證最後一次調用將會是最後一次執行。您的代碼有一個競爭條件,可能會導致在所有回調被執行之前發送響應 – carlosfigueira

+0

我看,謝謝分享 – kidwon