为什么在使用同步请求时我需要在请求之外返回值?

时间:2011-08-14 09:47:37

标签: javascript ajax mootools

我对同步请求有疑问。

背景:我需要在结账前立即获取用户的用户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或其他什么?

谢谢。

2 个答案:

答案 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)

问题在于范围。在第一个示例的情况下,您将从未分配给任何变量的匿名函数返回值。