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