我对同步请求有疑问。
背景:我需要在结账前立即获取用户的用户ID。如果userID为null或0,我将强制用户登录。我决定使用同步请求。我理解异步和同步请求之间的区别。但是我不明白为什么下面的第一个代码不起作用,但第二个代码不起作用。
...
UserId = GetUserId();
...
function GetUserId()
{
var jsonRequest = new Request({url: myurl, async: false, onComplete: function(result) {return result;}}).get();
}
当我使用上面的代码时,我得到UserId = undefined。但是,当我使用下面的代码时,它可以正常工作
...
UserId = GetUserId();
...
function GetUserId()
{
var resultreturned;
var jsonRequest = new Request({url: myurl, async: false, onComplete: function(result) {resultreturned = result;}}).get();
return resultreturned;
}
在我看来,在第一个代码中,即使我使用async:false,处理也不会停止。在第二个代码中它起作用。
有谁知道为什么?
另外,有没有办法在不使用var resultreturned的情况下访问返回的id?我可以使用类似
的方式访问返回返回jsonRequest.value或jsonRequest.result或其他什么?
谢谢。
答案 0 :(得分:0)
GetUserId
的第一个版本不会返回任何内容。就那么简单。匿名函数作为完成处理程序返回的东西返回并不重要;它的返回值传递给某些内部mootools函数并被忽略。
至于访问结果,基本XMLHttpRequest对象应该可以作为Request对象的xhr
属性访问(虽然这似乎不是Request's public interface的一部分)和响应(反过来)可以作为XHR对象的responseText
属性访问。简而言之,尝试:
jsonRequest.xhr.responseText
然而,这不应该是必要的。通过传递回调以在请求完成时运行,可以将任何同步请求转换为异步请求。您作为onComplete
参数传递的函数就是一个例子。这个技术名称为“continuation passing”(“continuation”在某种程度上是非正式的,“其余的计算,从给定点开始”)。
暂时忘掉调用堆栈。将return
语句假装为另一个函数。这个return
函数是一个延续;当它被调用时,其余的计算都会发生。切换到异步调用的第一步是让GetUserId
函数调用传入的延续而不是特殊的return
延续。
function GetUserId(succeed, fail)
{
var resultreturned;
var jsonRequest = new Request({url: myurl, async: false, onSuccess: function(result) {resultreturned = result;}, onFailure: fail}).get();
succeed(resultreturned);
}
要完成切换,请将继续传递到Request
而不是在GetUserId
中调用它,并使请求异步。
function GetUserId(succeed, fail)
{
new Request({url: myurl, onSuccess: succeed, onFailure: fail}).get();
}
...
function checkoutOrLogin(userId, responseXML) {
if (userId) {
/* continue checkout */
} else {
/* display login form */
}
}
GetUserId(checkoutOrLogin, function(xhr) {/* display error message */});
答案 1 :(得分:0)
问题在于范围。在第一个示例的情况下,您将从未分配给任何变量的匿名函数返回值。