Lodash: можно ли использовать map с асинхронными функциями?

рассмотрим этот код

const response  = await fetch('<my url>');
const responseJson = await response.json();
responseJson =  _.sortBy(responseJson, "number");

responseJson[0] = await addEnabledProperty(responseJson[0]);

что addEnabledProperty делает это, чтобы расширить объект добавив элемент enabled собственность, но это не важно. Сама функция работает хорошо

async function addEnabledProperty (channel){

    const channelId = channel.id;
    const stored_status = await AsyncStorage.getItem(`ChannelIsEnabled:${channelId}`);
    let boolean_status = false;
    if (stored_status == null) {
        boolean_status = true;
    } else {
        boolean_status = (stored_status == 'true');
    }

    return _.extend({}, channel, { enabled: boolean_status });
}

есть ли способ, чтобы использовать _.map (или другая система), чтобы цикл через весь массив responseJson использовать addEnabledProperty против каждого элемента?

пробовал:

responseJson = _.map(responseJson,  function(channel) {
            return addEnabledProperty(channell);
        });

но он не использует async, поэтому он замораживает приложение.

пробовал:

responseJson = _.map(responseJson,  function(channel) {
            return await addEnabledProperty(chanell);
        });

но я получил ошибку js (о строке return await addEnabledProperty(chanell);)

ожидание-зарезервированное слово

потом пробовал

responseJson = _.map(responseJson, async function(channel) {
            return await addEnabledProperty(channell);
        });

но я получил множество обещаний... и я не понимаю, почему...

что еще!??

редактировать: я понимаю ваши жалобы на то, что я не указал это addEnabledProperty() возвращает Promise, но, на самом деле, я не знаю. В на самом деле я написал:"я получил множество обещаний... и я не понимаю почему!--16--> "

4 ответов


для обработки вашего ответа jsons параллельно вы можете использовать Promise.all:

const responseJson = await response.json();
responseJson = _.sortBy(responseJson, "number");

let result = await Promise.all(_.map(responseJson, async (json) => 
  await addEnabledProperty(json))
);

С addEnabledProperty метод является асинхронным, следующее также должно работать (на @CRice):

let result = await Promise.all(_.map(responseJson, addEnabledProperty));

можно использовать Promise.all() для запуска всех обещаний в вашем массиве.

responseJson = await Promise.all(_.map(responseJson, async function(channel) {
        return await addEnabledProperty(channell);
    }));

я обнаружил, что мне не нужно было помещать асинхронный / await внутри Promise.all фантик.

используя это знание, в сочетании с цепью lodash (_.chain) может привести к следующей упрощенной версии принятого ответа:

const responseJson = await Promise.all( _
                       .chain( response.json() )
                       .sortBy( 'number' )
                       .map( json => addEnabledProperty( json ) )
                       .value()
                     )

Как насчет использования partial.js(https://github.com/marpple/partial.js)

оно покрывает и обещание и нормальную картину таким же кодом.

_p.map([1, 2, 3], async (v) => await setTimeout(console.log(v), 1000);