从回调和return获取数据到全局变量

Get data from callback and return to global variable

我正在尝试从回调中获取数据,并将这些数据放入全局变量中,就像这样。

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

console.log(x);

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

我必须做什么?谢谢大家。

PD:出于抓取的原因,我正在从水豚 execute_script 执行此操作,因此我需要 return x 以使用 evaluate_script.

获取数据

Michael 很好地说明了为什么您的实施不起作用。由于您正在进行异步调用,因此执行 javascript 的顺序是:

  1. 创建变量 x
  2. 发送Ajax呼叫
  3. 执行console.log(x)
  4. 将数据分配给 x(然后数据被 return 回传)

脚本在执行下一行之前不会等待数据return,因此在调用下一行时 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));

回答下面的评论

您将无法在第一次执行时 return x,因为 Ajax 调用 return 返回数据需要时间。如果您只是想 return 整个函数中的数据,那么将所有内容简化为这样可能更容易:

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();

您正在进行异步调用,因此 console.log() 发生在 AJAX 调用返回之前。 Jason 的例子对你有用。

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

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

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?

这应该会触发您的初始脚本,然后继续重试,直到 return 编辑了一个值。请注意,这是天真地假设一个非空值将被 returned,您可能需要 timeouts/better 值检查完全取决于被 returned 的数据。

如果在 Firefox 或 Chrome 中使用 selenium 驱动程序,您可以使用 seleniums execute_async_script 稍微清理一下,它将处理所有等待您的事情,而不是 return 直到回调(作为最后一个参数传递到脚本中 - 在这种情况下没有传递其他参数,因此回调脚本是 arguments[0])被调用。

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