嵌套承诺被卡住

Nested Promises Stuck

本文关键字:承诺 嵌套      更新时间:2023-09-26

以下代码被卡住:

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

然后陷入困境,不再执行任何代码。它永远不会到达那个时候,尽管已经实现了。

如果使用嵌套promise是一种反模式,那么在没有嵌套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');
            }
        });
    });
  });
};

在完成被称为之后,这也会被卡住

如果使用嵌套promise是一种反模式,那么在没有嵌套promise 的情况下如何执行以下操作

您不会使用async库。由于您的所有方法(element.all()el.getText()等)都已返回promise,因此不需要返回到节点样式的错误回调。根据我的"承诺规则",每个异步函数(即使是回调)都应该返回一个promise,并且使用库的方法来组合它们。您真的不需要自己调用Promise构造函数。您在那里进行的迭代可以通过mapels上轻松完成,然后将所有单个promise与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');
    });
}

以下代码解决了我的问题,主要是由于我对量角器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-promise继承而来的,不幸的是,它并不完全符合promise A+。