use*_*616 0 javascript azure azure-table-storage azure-mobile-services
因此,在我的服务器代码中,变量邀请在成功函数之外是未定义的.
function getInvites(id){
var InvitesTable = tables.getTable("Invites").where({"PlanID": id}).select("UserID","Attending");
var invites;
InvitesTable.read({ success: function(resultss) {
invites = resultss;
console.log(invites); //works here
}});
console.log(invites); //undefined here
}
Run Code Online (Sandbox Code Playgroud)
从类似的问题,我意识到它是因为它是异步的.因此,调用后运行成功函数console.log(invites); //undefined here调用.
我的问题是如何在Windows Azure中停止它?
添加了代码
function read(query, user, request) {
request.execute({
success: function(results) {
results.forEach(function(r) {
getInvites(r.id, function(invites) {
r.invites = invites;
});
});
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);
}});
}
Run Code Online (Sandbox Code Playgroud)
你没有"停止",你围绕你正在使用的任何环境的异步性质设计你的应用程序.
我假设你正在尝试做这样的事情:
function getInvites(id){
var InvitesTable = tables.getTable("Invites").where({"PlanID": id}).select("UserID","Attending");
var invites;
InvitesTable.read({ success: function(resultss) {
invites = resultss;
}});
return invites;
}
// later...
var invites = getInvites(someId);
//do something with `invites`
Run Code Online (Sandbox Code Playgroud)
这显然不起作用,因为您invites在异步调用完成之前返回值.
相反,您以异步方式编写应用程序:
function getInvites(id, cb){
var InvitesTable = tables.getTable("Invites").where({"PlanID": id}).select("UserID","Attending");
InvitesTable.read({ success: function(resultss) {
if (cb) cb(resultss);
}});
}
// later...
getInvites(someId, function(invites) {
//do something with `invites`
});
Run Code Online (Sandbox Code Playgroud)
为简单起见,这省略了错误处理代码,因此您也必须添加它.
看到完整的代码后,看起来你有一个管理许多并行异步操作的简单问题.考虑一下发生了什么:你的循环运行,迭代n个对象的数组.对于每个,您调用getInvites,它开始一个数据库请求并返回.
这意味着您的循环运行速度非常快,但现在您有n个未完成的数据库请求,您必须等待才能调用request.respond().
一个非常基本的解决方案是做一些事情,比如计算你的getInvites回调被调用的次数,然后当该数字达到n时最终完成请求.
但是,每次发出异步请求时,手动管理此簿记都非常耗时且容易出错.这是流控制库非常有用的情况.我将Deferred在这个例子中使用jQuery ,因为它可能已经为你所熟悉(即使你以前不知道你实际使用过它 - 如果你曾经使用过jQuery的XHR API,你已经使用了Deferreds).
鉴于你在服务器环境中,你显然没有jQuery; 但是,有些人只提取Deferred了你需要的代码.
一旦我们Deferred为每个待处理请求提供了s,我们就可以使用when注册一个只在所有挂起Deferreds完成后才被调用的回调.
function read(query, user, request) {
request.execute({
success: function(results) {
var dfds = [];
for (var i = 0; i < results.length; i++) {
dfds.push(getInvites(results[i].id)); // Makes an array of Deferreds representing
// each of our pending requests.
}
Deferred.when.apply(Deferred, dfds) // see details below
.done(function() {
for (var i = 0; i < results.length; i++) {
results[i].invites = arguments[i]; // Copy each set of invites to each result
}
request.respond(); // We're done!
})
.fail(function() {
// Handle errors here
});
}
});
}
function getInvites(id){
var dfd = new Deferred(); // Create a new Deferred, which automatically starts in the 'pending' state
var InvitesTable = tables.getTable("Invites").where({"PlanID": id}).select("UserID","Attending");
InvitesTable.read({ success: function(results) {
dfd.resolve(results); // When we get data back, we 'resolve' the Deferred --
// in other words, say its operation is done,
// and pass along the operation's results.
},
error: function(err) { // TODO: Not sure if this is how the API you're using handles errors
dfd.reject(err); // Marks the Deferred as failed.
}});
return dfd.promise(); // We (synchronously) return the Promise. The caller can attach event handlers
// to the Promise, which are invoked when we eventually resolve or reject the Deferred.
}
Run Code Online (Sandbox Code Playgroud)
笔记:
jQuery.when(或在此服务器端的情况下,Deferred.when)通常希望您传递固定数量的Deferreds作为参数:
$.when(dfd1, dfd2).done(function(result1, result2) { ... });
Run Code Online (Sandbox Code Playgroud)
但是,我们有一个可变数量的Deferreds,所以我们必须有apply一个Deferreds 数组,when然后在done处理程序中,通过隐式arguments对象访问每个结果.
Array.forEach(...) 很慢.在大多数情况下,最好使用常规for循环.
| 归档时间: |
|
| 查看次数: |
1447 次 |
| 最近记录: |