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

发布于 2024-11-29 11:55:06 字数 864 浏览 0 评论 0 原文

我有一个关于同步请求的问题。

背景:我需要在结帐前立即获取用户的用户ID。如果 userID 为空或零,我将强制用户登录。我决定使用同步请求。我了解异步请求和同步请求之间的区别。但是我不明白为什么下面的第一个代码不起作用,但第二个代码却起作用。

...
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? 内容来访问返回吗

我可以使用return jsonRequest.value 或 jsonRequest.result 或其他

?谢谢。

I have a question about sync requests.

Background: I need to get the userID of the user immediately before checkout. If userID is null or zero I will force the user to login. I decided to use the synchronous request. I understand the difference between async and sync requests. However I don't understand why the first code below does not work, but the second does.

...
UserId = GetUserId();
...

function GetUserId()
{
  var jsonRequest = new Request({url: myurl, async: false, onComplete: function(result) {return result;}}).get();
}

When I use the code above, I get UserId = undefined. However it works when I use the code below

...
UserId = GetUserId();
...

function GetUserId()
{
  var resultreturned;
  var jsonRequest = new Request({url: myurl, async: false, onComplete: function(result) {resultreturned = result;}}).get();
  return resultreturned;
}

It seems to me that in the first code, the processing does not stop even though I used the async:false. In the second code it works.

Does anyone know why?

In addition, is there a way to access the returned id without using the var resultreturned? Can I access the return using something like

return jsonRequest.value or jsonRequest.result or something else?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

泪是无色的血 2024-12-06 11:55:06

GetUserId 的第一个版本不返回任何内容。就这么简单。作为完成处理程序传递的匿名函数返回一些内容并不重要;它的返回值被传递给一些内部 mootools 函数并被忽略。

至于访问结果,基本 XMLHttpRequest 对象应该可以作为 Request 对象的 xhr 属性进行访问(尽管这似乎不是 请求的公共接口),并且响应(反过来)可以作为 XHR 对象的 responseText 属性。简而言之,尝试一下:

jsonRequest.xhr.responseText

但是,这不是必需的。任何同步请求都可以通过传递回调以在请求完成时运行来转换为异步请求。您作为 onComplete 参数传递的函数就是一个示例。其技术名称为“连续传递”(“延续”,有点非正式地说,“其余的计算,从给定点向前”)。

暂时忘记调用堆栈。将 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 */});

The first version of GetUserId doesn't return anything. Simple as that. That the anonymous function passed as the completion handler returns something doesn't matter; its return value is passed to some internal mootools function and is ignored.

As for accessing the result, the base XMLHttpRequest object should be accessible as the xhr property of the Request object (though this doesn't appear to be part of Request's public interface), and the response (in turn) is accessible as the responseText property of the XHR object. In short, try:

jsonRequest.xhr.responseText

However, this shouldn't be necessary. Any synchronous request can be turned into an asynchronous request by passing along a callback to run when the request completes. The function you pass as the onComplete argument is an example of this. This has the technical name of "continuation passing" (a "continuation" is, somewhat informally, "the rest of the calculation, from a give point forward").

Forget about call stacks for a moment. Pretend the return statement as just another function. This return function is a continuation; when it's called, the rest of the calculation happens. The first step in switching to asynchronous calls is to have your GetUserId function call the continuation passed in instead of special return continuation.

function GetUserId(succeed, fail)
{
  var resultreturned;
  var jsonRequest = new Request({url: myurl, async: false, onSuccess: function(result) {resultreturned = result;}, onFailure: fail}).get();
  succeed(resultreturned);
}

To finish the switch, pass the continuation on to Request rather than invoking it in GetUserId, and make the request asynchronous.

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 */});
小女人ら 2024-12-06 11:55:06

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

The problem is of the scope. In the case of the first example, you are returning value from an annonymous function that is not assigned to any variable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文