我正在尝试编写一个函数(使用WebdriverJS lib),该函数遍历元素列表,检查名称并构建与该名称对应的xpath定位器。我在这里简化了xpath定位器,所以不要注意。
我面临的问题是: 1)调用此函数将返回undefined。据我了解,这是因为return语句不在位,但是: 2)将它放在同步代码通常正常工作的正确位置,对异步承诺不起作用,因此调用此函数将返回相同的undefined,但因为return语句在"驱动程序之前触发。 findElement"言。
如果我想通过调用这个函数得到createdTask变量,我应该如何在这里使用return语句?
var findCreatedTask = function() {
var createdTask;
driver.findElements(By.xpath("//div[@id='Tasks_Tab']")).then(function(tasks) {
for (var index = 1; index <= tasks.length; index++) {
driver.findElement(By.xpath("//div[@id='Tasks_Tab'][" + index + "]//div[@class='task-title']")).getText().then(function(taskTitle) {
if (taskTitle == "testName") {
createdTask = "//div[@id='Tasks_Tab'][" + index + "]";
return createdTask;
}
});
}
});
};
答案 0 :(得分:1)
您将无法从此函数返回所需的值,因为当此函数返回时,该值尚未定义。
尝试在错误的位置返回值,但尝试在错误的时间访问它时,这不是问题。
您有两个选择:您可以从此函数返回一个promise,或者此函数可以接受在值可用时调用的回调。
这未经过测试,但应该让您了解如何思考它。
有承诺的版本:
public void requestWithSomeHttpHeaders() {
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest postRequest = new StringRequest(Request.Method.POST,"http://12.211.156.201/SOWebService/Service.asmx/GetCompany",
new Response.Listener<String>()
{
@Override
public void onResponse(String response) {
System.out.println(response);
}
},
new Response.ErrorListener()
{
@Override
public void onErrorResponse(VolleyError error) {
System.out.println(error.toString() + "--" + error.getCause());
// TODO Auto-generated method stub
Log.d("ERROR","error => "+error.toString());
// definitions.setText("check your internet connection");
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
System.out.println("1");
} else if (error instanceof AuthFailureError) {
System.out.println("2");
//TODO
} else if (error instanceof ServerError) {
System.out.println("3");
//TODO
} else if (error instanceof NetworkError) {
System.out.println("4");
//TODO
} else if (error instanceof ParseError) {
System.out.println("5");
//TODO
}
}
}
)
{
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Token", token);
return params;
}
@Override
protected Map<String, String> getParams() throws AuthFailureError {
// return super.getParams();
Map<String, String> params = new HashMap<String, String>();
params.put("groupName", "avd");
params.put("userCode", "ADMIN");
return params;
}
};
queue.add(postRequest);
}
然后你用:
来调用它var findCreatedTask = function (callback) {
var createdTask;
return new Promise(function (resolve, reject) {
driver.findElements(By.xpath("//div[@id='Tasks_Tab']")).then(function(tasks) {
for (let index = 1; index <= tasks.length && !createdTask; index++) {
driver.findElement(By.xpath("//div[@id='Tasks_Tab'][" + index + "]//div[@class='task-title']")).getText().then(function(taskTitle) {
if (taskTitle == "testName") {
createdTask = "//div[@id='Tasks_Tab'][" + index + "]";
resolve(createdTask);
}
});
}
});
});
};
带回调的版本:
findCreatedTask().then(function (createdTask) {
// you have your createdTask here
});
然后你用:
来调用它var findCreatedTask = function (callback) {
var createdTask;
driver.findElements(By.xpath("//div[@id='Tasks_Tab']")).then(function(tasks) {
for (let index = 1; index <= tasks.length && !createdTask; index++) {
driver.findElement(By.xpath("//div[@id='Tasks_Tab'][" + index + "]//div[@class='task-title']")).getText().then(function(taskTitle) {
if (taskTitle == "testName") {
createdTask = "//div[@id='Tasks_Tab'][" + index + "]";
callback(null, createdTask);
}
});
}
});
};
如果您有兴趣了解承诺和回调,您可以阅读一些解释承诺和回调如何运作的其他答案:
答案 1 :(得分:1)
在这里,我清理了一下。如果在嵌套的promise中有经验,这实际上会返回错误:
int Count2(struct node **head)
{
printf("entered");
struct node *temp;
int count = 1;
temp = (*head); // pointers to the first
while (temp->next != *head) // direct pointer comparison
{
printf("entered");
temp = temp->next; // natural linked-list exploration
count++;
}
return count;
}
您使用
调用它var findCreatedTask = function() {
var Promise = require('bluebird');
var createdTask;
return driver.findElements(By.xpath("//div[@id='Tasks_Tab']"))
.then(function(tasks) {
return Promise.map(tasks, function(task){
return driver.findElement(By.xpath("//div[@id='Tasks_Tab'][" + index + "]//div[@class='task-title']")).getText()
}).then(function(taskTitles){
for (let i = 0; i < taskTitles.length; i++){
if(taskTitles[i] === 'testName'){
createdTask = "//div[@id='Tasks_Tab'][" + i + "]";
return createdTask;
}
}
});
});
};
答案 2 :(得分:1)
您可以先使用promise.map
获取所有文字,然后使用indexOf
获取该位置:
var map = webdriver.promise.map;
var findCreatedTask = function() {
var elems = driver.findElements(By.xpath("//div[@id='Tasks_Tab']//div[@class='task-title']"));
return map(elems, elem => elem.getText()).then(titles => {
var position = titles.indexOf("testName") + 1;
return "//div[@id='Tasks_Tab'][" + position + "]";
});
}