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