Q.Promise масив, предупреждение, ако е изпълнено повече от 1

Използвам Q библиотека за работа с обещания. Да кажем, че имам набор от обещания, които чакам първото да бъде изпълнено, за да върна стойността си.

Очаквам само едно от обещанията да бъде изпълнено, но не мога да гарантирам тази ситуация и затова бих искал да направя НЕЩО, ако друго обещание е изпълнено след първото.

Очевидно бих могъл да използвам Q.allSettled, но тогава ще трябва да изчакам всички обещания да бъдат изпълнени/отхвърлени, преди да мога да получа достъп до стойността на първото изпълнено обещание.

Чудех се дали има начин за достъп до стойността на първото обещание, което да бъде върнато, докато все още обработвам другите обещания, за да мога да предупредя, ако друго обещание е изпълнено.

Надявам се, че въпросът ми е ясен, благодаря за помощта.

Edit1 - кодов фрагмент

Както можете да видите, този код връща стойността на първото изпълнено обещание. Искам да запазя това поведение, като същевременно мога да предприема действия, ако бъде изпълнено второ обещание.

var getDataSourcePromise = function(table, profileId) {
    var deferred = Q.defer();

    table.retrieveEntity(tableName, profileId, profileId, function(err, result, response) {
        if (err) {
            deferred.reject(Error(err));
        }
        else {
            deferred.resolve(result);
        }
    });

    return deferred.promise;
}

var promises = [];
tables.forEach(function(table, profileId) {
    promises.push(getDataSourcePromise(table, profileId.toString()));
});

console.log('waiting for settle');

Q.any(promises).then(function(result) {
    console.log(result);
});

Edit2 - повече информация

Като се има предвид, че разбирате какво трябва да прави горният код, имам обобщена GetDataSource(profileId): Q.Promise<DataSource> функция (input: profileId, output: a promise for a DataSource).

Трябва да върна стойността на първото изпълнено обещание на този, който ми се е обадил, веднага щом е изпълнено --- което означава, че трябва да върна Q.any(promises). От друга страна, все още трябва да изпълня тази част от кода (на Benjamin Gruenbaum):

Q.allSettled(promises).then(function(result){
    if(result.filter(function(p){ return p.state === "fulfilled"; })){
       alert("Sanity failure"); // do whatever you need to recover
    }
});

Какво препоръчвате да направя? (съжалявам, че не бях достатъчно ясен преди)


person johni    schedule 13.12.2015    source източник
comment
Бихте ли публикували примерен кодов фрагмент, за да демонстрирате вашата ситуация, за да разберем по-лесно въпроса ви?   -  person Aycan Yaşıt    schedule 13.12.2015
comment
добавен кодов фрагмент според заявката.   -  person johni    schedule 13.12.2015


Отговори (1)


Можете да разклоните обещания и да създадете множество клонове:

var promises = tables.map(function(table) { 
    return getDataSourcePromise(table, profileId.toString());
});

Q.any(promises).then(function(result){
   console.log("Result", result); // processing done
});
Q.allSettled(promises).then(function(result){
    if(result.filter(function(p){ return p.state === "fulfilled"; })){
       alert("Sanity failure"); // do whatever you need to recover
    }
});
person Benjamin Gruenbaum    schedule 13.12.2015
comment
Здравейте, благодаря за отговора, очевидно не предоставих информация и съжалявам за това, можете ли да прочетете Edit2? Вашият отговор обаче ми помогна да разбера нещо друго.. - person johni; 13.12.2015
comment
@johni Не разбирам, решението ми все още работи след редакцията, просто return Q.any и поставете allSettled над него? - person Benjamin Gruenbaum; 13.12.2015
comment
По този начин .then на Q.allSettled ще се изпълни, след като Q.any бъде върнат на повикващия и програмата продължи да работи? - person johni; 13.12.2015
comment
Джони, ти каза, че искаш да направиш нещо, ако друго обещание е изпълнено след първото. Предупреждението за здравия разум тук не се ли случва за всички успешни отговори, включително първия? - person Roamer-1888; 14.12.2015