问题
So for the past few hours I've been looking into async stuff and using promises. I'm using the testing framework protractor, and theres a few async things I'm having trouble with.
In this save function, I call cm.org1.all() asynchronously, and use then to get the response. I loop over the response, and I need call getNewElement() to each element in the response, which also has an async call in it, so each returns a promise.
So I have this array of promises, but I don't know how to return it. The return of cm.save() is []. I need it to be ['foo',foo',foo',foo']
This code below doesn't work, but it's what I have so far.
var cm = companyManagement() {
//whatever is initialized below is initialized up here
this.save = function() {
cm.saveButton.click();
var elements;
var promises = [];
var defer = protractor.promise.defer();
cm.org1.all(by.repeater('brand in vm.brands'))
.then(function(response) {
//elements is of length 4
elements = response;
for(var i=0; i<elements.length;i++) {
promises.push(getNewElement(elements, i));
}
//defer.fulfill(promises); not correct?
});
return protractor.promise.all(promises); //not correct?
};
function getNewElement(elements, i) {
var defer = protractor.promise.defer();
var alias = elements[i].element(by.binding('brand.alias'));
alias.getText().then(function(aliasText) {
defer.fulfill('foo');
});
return defer.promise;
}
}
cm.save()
.then(function(response){
console.log("my new array is",response);
});
回答1:
Dealing with protractor promises manually in your tests is usually a sign of overcomplicating a problem. Protractor
has a variety of abstractions and functional programming tools that cover most of the use cases.
You can solve it in just a single line if you would use repeater's .column():
this.save = function() {
cm.saveButton.click();
return cm.org1.all(by.repeater('brand in vm.brands').column('brand.alias')).getText();
};
I would do this, but I want to eventually be able to get the element's parent, if the column brand.alias matches with a certain constant I have. if I only have the alias text I couldn't be able to get the parent, correct me if I'm wrong.
filter() and map() to the rescue:
cm.org1.all(by.repeater('brand in vm.brands').column('brand.alias')).filter(alias) {
return alias.getText().then(function (aliasText) {
return aliasText === "foo";
});
}).map(function (alias) {
return alias.element(by.xpath("..")).getText(); // getting the parent
});
回答2:
Try:
this.save = function() {
cm.saveButton.click();
var elements;
var promises = [];
var defer = protractor.promise.defer();
return cm.org1.all(by.repeater('brand in vm.brands'))
.then(function(response) {
//elements is of length 4
elements = response;
for(var i=0; i<elements.length;i++) {
promises.push(getNewElement(elements, i));
}
return protractor.promise.all(promises);
});
};
来源:https://stackoverflow.com/questions/33921760/how-can-i-return-an-array-of-promises-in-a-then-statement