асинхронное или обещанное условие для фильтра массива

Мне нужно отфильтровать массив на основе условия, которое можно проверить только асинхронно.

return someList.filter(function(element){ 
   //this part unfortunately has to be asynchronous
})

Есть ли более приятный способ сделать это с обещаниями, чем то, что у меня уже есть?

В этом фрагменте для промисов используется Q, но на самом деле вы можете предположить любую правильную реализацию промисов.

return q.all(someList.map(function (listElement) {
        return promiseMeACondition(listElement.entryId).then(function (condition) {
            if (condition) {
                return q.fcall(function () {
                    return listElement;
                });
            } else {
                return q.fcall(function(){});
            }
        });
    }));

Пример кода преобразует обещание в отфильтрованный массив, и это желаемый результат.


person naugtur    schedule 26.03.2014    source источник
comment
Ответ на этот вопрос связан с: существует подход, основанный на чистом обещании, для сопоставления конкатенации коллекций "> stackoverflow.com/questions/18017980/, но вопрос слишком запутанный и конкретный, чтобы быть дублирующим ИМХО   -  person naugtur    schedule 26.03.2014


Ответы (1)


В таких библиотеках, как Bluebird, у вас есть встроенные методы, такие как .map и .filter промисов. Ваш подход в целом правильный. Вам просто не хватает Array.prototype.filter в конце, удаляя "плохие результаты" - например, разрешить с константой BadValue и отфильтровать элементы, которые равны ей.

var BadValue = {};

return q.all(someList.map(function (listElement) {
        return promiseMeACondition(listElement.entryId).then(function (listElement) {
            return (condition(listElement)) ? listElement : BadValue;
    })).then(function(arr){
            return arr.filter(function(el){ return el !== BadValue; });
    });

С Блубердом:

  Promise.filter(someList,condition);

Конечно, вы можете извлечь эту функциональность в общую функцию filter для промисов.

person Benjamin Gruenbaum    schedule 26.03.2014