从回调中获取数据并返回到全局变量

时间:2017-06-02 23:31:01

标签: javascript capybara

我试图从回调中获取数据,并将此数据放入全局变量中,如下所示。

var x;
  CartolaRutAccountAJAXFacade.getCargarValores(dwr.util.byId('combo').value, function(data){
    x = data;
  });

console.log(x);

在控制台日志中我未定义。 如果我在几秒钟后执行x,我会得到正确的数据。

我该怎么办?谢谢他们。

PD:我是从capybara execute_script做的,因为抓取原因,所以我需要返回x来获取带有evaluate_script的数据。

3 个答案:

答案 0 :(得分:1)

迈克尔为你的实施工作原理提出了一个很好的观点。由于您正在进行异步调用,因此执行javascript的顺序为:

  1. 创建变量x
  2. 发送Ajax电话
  3. 执行console.log(x)
  4. 将数据分配给x(当返回数据时)
  5. 在执行下一行之前,脚本不会等待数据返回,因此当调用下一行时x尚未分配给数据。

    如果您需要以某种方式处理数据,您应该创建一个函数并在回调中调用该函数:

    var x;
    
    function handleData() {
        console.log(x);
    }
    
    CartolaRutAccountAJAXFacade.getCargarValores(dwr.util.byId('combo').value, function(data){
        x = data;
        handleData();
    });
    

    或者,如果需要,可以通过参数将数据传递给函数,而不是将其分配给x或使用匿名函数。

    function handleData(data) {
        console.log(data);
    }
    
    CartolaRutAccountAJAXFacade.getCargarValores(dwr.util.byId('combo').value, handleData(data));
    

    回答下面的评论

    在第一次执行时,您无法在第一次执行时返回x,因为Ajax调用需要时间来返回数据。如果您只是尝试从整个函数中返回数据,则可能更容易将所有内容简化为:

    useLoadingMessage();
    dwr.engine.beginBatch();
    
    CartolaRutAccountAJAXFacade.getCargarValores(dwr.util.byId('combo').value, function(data){
    
        console.log(data);
    
        // You may also want to do this, if you are looking 
        // to return the data from within evaluate_script:
        //
        // return data; 
    
    });
    
    dwr.engine.endBatch();
    

答案 1 :(得分:0)

您正在进行异步调用,因此在返回AJAX调用之前发生了console.log()。杰森的例子适合你。

答案 2 :(得分:0)

正如其他答案中所提到的,这里真正的问题是你正在进行异步通话而且无法知道(来自Capybara)该通话何时结束。根据您为Capybara使用的驱动程序,有几种可能的解决方案。

对于所有支持JS的驱动程序,您应该能够将值存储在窗口中的变量中,然后在循环中检索直到非零

session.execute_script("CartolaRutAccountAJAXFacade.getCargarValores(dwr.util.byId('combo').value, function(data){
window.my_value = data;})")

begin
  sleep 0.05;
  my_val = session.evaluate_script("window.my_value")
end while my_val.nil?

应触发您的初始脚本,然后继续重试,直到返回一个值。注意,这是天真地假设将返回非空值,您可能需要超时/更好的值检查,具体取决于返回的数据。

如果在Firefox或Chrome上使用selenium驱动程序,可以使用selenium execute_async_script来清理这一点,它会处理所有等待你的事情,直到回调后才会返回(传入脚本)作为最后一个参数 - 在这种情况下没有传递其他参数,因此调用回调脚本arguments[0])。

session.driver.browser.execute_async_script("CartolaRutAccountAJAXFacade.getCargarValores(dwr.util.byId('combo').value, arguments[0])")