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);