Массив 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);
});

Редактировать2 – больше информации

Учитывая, что вы понимаете, что должен делать приведенный выше код, у меня есть обобщенная функция GetDataSource(profileId): Q.Promise<DataSource> (input: profileId, output: a promise for a DataSource).

Мне нужно вернуть значение первого выполненного обещания тому, кто мне позвонил, как только оно было выполнено --- то есть мне нужно вернуть Q.any(promises). С другой стороны, мне все еще нужно выполнить эту часть кода (Бенджамина Грюнбаума):

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