简体   繁体   English

我可以从jQuery中的匿名回调函数返回数据吗?

[英]Can I return data from an anonymous callback function in jQuery?

I'm sure this is simple, but I'm tripping up over a scope issue in Javascript. 我敢肯定这很简单,但是我将探讨Javascript中的范围问题。 I'm doing the following: 我正在执行以下操作:

$.get(url, function (data){console.log(data);});

This part works fine - I see the string that I want appear in the console. 这部分工作正常-我在控制台中看到了想要的字符串。 But what I actually want is to take that data variable and place it in a string. 但是我真正想要的是获取该数据变量并将其放入字符串中。 Something like this (doesn't work): 这样的事情(无效):

string = $.get(url, function (data){return data;});

This gives string a value of [object XMLHttpRequest] . 这为string提供了[object XMLHttpRequest]的值。

What am I missing? 我想念什么?

Oops 哎呀

Yes, I'm missing the fact that Ajax is, as the name says, asynchronous. 是的,我错过了一个事实,正如其名称所说,Ajax是异步的。 Thanks for giving me the slap on the forehead I needed, everyone. 谢谢大家给我拍我需要的额头。

Afterword 后记

The reason I wasn't simply working with the results inside the callback function itself is that I actually need to do multiple AJAX requests every few seconds, gather up the data, and append them all to the page when they're all done. 我之所以不简单地使用回调函数内部的结果,是因为我实际上需要每隔几秒钟执行多个AJAX请求,收集数据并将它们全部添加到页面之后。

I've now got that working with a little closure function - the requests are done in a loop, and the data is passed to the closure. 现在,我有了一个小的闭包功能-请求在一个循环中完成,并将数据传递到闭包。 When the timer goes off, I call the closure function with no arguments, which tells it "append your previous batch of data to the page (the requests are surely complete by now), clear your cache, and prepare to start receiving new data from the AJAX callbacks in my loop." 当计时器关闭时,我不带参数的情况下调用了关闭函数,它告诉它“将您的前一批数据追加到页面上(请求现在肯定已经完成了),清除了缓存,并准备开始从中接收新数据我的循环中的AJAX回调。”

Which (hopefully) shows that I'm not an idiot after all. 哪一个(希望)表明我毕竟不是白痴。 :) :)

.get() sends an AJAX GET HTTP request and returns immediately meaning that you cannot assign the result to a variable simply because the result is only available in the success callback (the anonymous function you are passing as second argument). .get()发送AJAX GET HTTP请求并立即返回,这意味着您不能仅将结果分配给变量,因为结果仅在成功回调(您作为第二个参数传递的匿名函数)中可用。 In this callback you could call another functions and pass the data as variable. 在此回调中,您可以调用其他函数并将数据作为变量传递。 That's just how AJAX works. 这就是AJAX的工作方式。 The A stands for asynchronous. A代表异步。

Returning data from the callback function only returns it to the caller of that callback function, which is jQuery, which does nothing with it. 从回调函数返回数据仅将其返回给该回调函数的调用者,即jQuery,它对此不执行任何操作。

What you can't do is pass that value from the callback function into the assignment in the surrounding function, and the reason you can't do that is because it would be time travel. 您不能做的就是将该值从回调函数传递到周围函数的赋值中,而您之所以不能这样做,是因为这将花费时间。 The get() method returns instantly, starting off an HTTP request in the background that will complete later. get()方法立即返回,在后台启动一个HTTP请求,该请求稍后将完成。 When it does, the callback function is called, but by that time the string has long ago been assigned. 这样做时,将调用回调函数,但到那时该string已很久就被分配了。

You can't call asynchronous code synchronously, or vice versa. 您不能同步调用异步代码,反之亦然。 If you want to do something with the result of the HTTP request, you can only do that in a callback function. 如果要对HTTP请求的结果进行处理,则只能在回调函数中进行处理。 If you want to provide a function that makes an HTTP request and passes the result back, you have to do it by accepting and calling a callback function yourself: 如果要提供一个发出HTTP请求并将结果传回的函数,则必须自己接受并调用一个回调函数来做到这一点:

function getThing(callback) {
    ...
    $.get(url, function(data) {
        callback(data);
    });
}

The alternative is to do the whole lot synchronously, using async: false . 另一种方法是使用async: false同步完成全部操作。 But that's bad news for everyone, as the web browser hangs up until the request is complete. 但这对每个人来说都是个坏消息,因为网络浏览器会挂起直到请求完成。

Ajax requests are done asynchronously 1 , the last argument of the JQuery's ajax functions is a callback. Ajax请求是异步完成的1 ,JQuery的ajax函数的最后一个参数是回调。 To answer why your second example doesn't work, you need to understand async callbacks . 要回答为什么第二个示例不起作用,您需要了解异步回调 Alternately, this is similar to the observer pattern where the observable is the Ajax request and the observer is the callback. 或者,这类似于观察者模式,其中observable observer是Ajax请求, observer是回调。 The steps to perform a request are (roughly) : 执行请求的步骤大致是:

  1. create an XmlHttpRequest object 创建一个XmlHttpRequest对象
  2. build the request and send it 建立请求并发送
  3. wait for response 等待回应
  4. receive a response (there are different states there) 收到响应(那里有不同的状态)
  5. processing the response 处理回应
  6. Notifying the callback 通知回调

The argument data in the callback arrives at step 6, while the $.get() call returns at step 2. So your data is not available. 回调中的参数data到达步骤6,而$.get()调用返回到步骤2。因此您的数据不可用。 You need to set the data at step 6 in some variable and process it from there. 您需要在第6步中的某个变量中设置数据,然后从那里进行处理。


1 requests can be done synchronously, however the A in Ajax stands for Asynchronous . 1个请求可以同步完成,但是Ajax中的A代表Asynchronous One could use $.get() to perform a synchronized request, but could not be technically called "Ajax". 可以使用$.get()来执行同步请求,但是从技术上讲,它不能称为“ Ajax”。 My point of view. 我的观点。

that data var being passed to your anonymous function is the ajax object itself. 传递给匿名函数的数据变量就是ajax对象本身。 If you want to return the response text from the server, you would do something like this: 如果要从服务器返回响应文本,请执行以下操作:

$.get(url, 
    // data to send
    {
      'foo' : 'bar'
    },
    // receive response
    function(response){
      return response;
    } // response callback function
); // .get()

you could do one of two things: 您可以执行以下两项操作之一:

1 - change your GET to be synchronous with {async: false } , you may need to use the $.ajax method to do that. 1-将GET更改为与{async: false }同步,您可能需要使用$ .ajax方法。 then assign the variable inside the success callback. 然后在成功回调中分配变量。

2 - put whatever you have that is using the variable inside the success callback. 2-将使用变量的所有内容放入成功回调中。

$.get(url, function (data){
    var string = data;
    useMyString(string);
});

This is what you're trying: 这是您要尝试的:

var data = $.get(url, function(data){return data;});
// trying to do the stuff you want to do with data

This is what you need to do: 这是您需要做的:

$.get(url, function(data){
    // do the stuff you want to do with data
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM