从回调和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 的顺序是:
- 创建变量 x
- 发送Ajax呼叫
- 执行console.log(x)
- 将数据分配给 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])")
我正在尝试从回调中获取数据,并将这些数据放入全局变量中,就像这样。
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 的顺序是:
- 创建变量 x
- 发送Ajax呼叫
- 执行console.log(x)
- 将数据分配给 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])")