嵌套的承诺被困住了

时间:2014-10-10 08:54:10

标签: javascript node.js asynchronous promise protractor

以下代码被卡住了:

var Promise = require('promise');
var testPromise = function(){
  return new Promise(function(fulfill, reject){

    element.all(by.repeater('item in menu.items')).first().then(function(el){
        console.log('test f');
        fulfill(el);
        console.log('test fe');
    });

  });
};

......由以下人员调用:

testPromise().then(function(el){
    console.log('test successful '+el);
});

控制台打印

test f
test fe

卡住了,不再执行代码了。它永远不会到达当时,尽管已经被称为。

如果使用嵌套的promises是反模式,那么如果没有嵌套的promise,我该怎么做呢:

var getMenuItemEl = function(itemName){
  return new Promise(function(fulfill, reject){

    var elFound;
    element.all(by.repeater('item in menu.items')).then(function(els){
        async.each(els, function(el, callback){
            el.getText().then(function(text){
                console.log('getMenuItemEl:'+text);
                if(text === itemName){
                    elFound = el;
                }
                callback(); 
            });
        }, function(err){
            console.log('complete '+elFound);
            if(elFound){
                console.log('fulfill');
                fulfill(elFound);
                console.log('after fulfill');
            }else{
                reject('no item found');
            }
        });

    });

  });
};

在调用完成后,这也会被卡住

2 个答案:

答案 0 :(得分:2)

  

如果使用嵌套的promises是反模式,那么如何在没有嵌套的promise

的情况下执行以下操作

您不会使用async库。由于您的所有方法(element.all()el.getText()等)都已经返回了promises,因此您无需返回节点式错误回调。来自my "rules for promises"每个异步函数(即使它是回调函数)都应该返回一个承诺,并且使用您的库的方法来构成它们。你真的不需要自己调用Promise构造函数。你在那里进行的迭代可以通过els上的map轻松完成,然后将所有单一承诺与Promise.all一起收集。

function getMenuItemEl(itemName) {
    return element.all(by.repeater('item in menu.items'))
    .then(function(els){
        return Promise.all(els.map(function(el) {
            return el.getText()
            .then(function(text){
                console.log('getMenuItemEl:'+text);
                return (text === itemName) ? el : null;
            });
        }));
    })
    .then(function(foundEls) {
        for (var i=0; i<foundEls.length; i++)
            if (foundEls[i] != null) {
                console.log('fulfill');
                return foundEls[i];
            }
        throw new Error('no item found');
    });
}

答案 1 :(得分:0)

以下代码解决了我的问题,主要是由于我对量角器api缺乏了解

var doClickMenuItemEl = function(itemName){
  return element.all(by.repeater('item in menu.items')).filter(function(elem, index) {
    return elem.getText().then(function(text) {
        return text === itemName;
    });
  }).then(function(els){
    els[0].click();
  });   
};

它还在https://github.com/angular/protractor/issues/379上说

  

是的,这是继承自webdriver的承诺,不幸的是,它不太符合A +标准。