Я использую async.eachLimit
функцию для управления максимальным количеством операций за раз.
const { eachLimit } = require("async");
function myFunction() {
return new Promise(async (resolve, reject) => {
eachLimit((await getAsyncArray), 500, (item, callback) => {
// do other things that use native promises.
}, (error) => {
if (error) return reject(error);
// resolve here passing the next value.
});
});
}
Как видите, я не могу объявить myFunction
функцию как асинхронную, потому что у меня нет доступа к значению во втором обратном вызове eachLimit
функции.
javascript
node.js
asynchronous
async-await
Алексис Тайлер
источник
источник
Ответы:
Вы эффективно используете обещания внутри функции-исполнителя конструктора обещаний, поэтому это анти-шаблон конструктора обещаний .
Ваш код является хорошим примером основного риска: небезопасного распространения всех ошибок. Почитай почему там .
Кроме того, использование
async
/await
может сделать те же самые ловушки еще более удивительными. Сравните:let p = new Promise(resolve => { ""(); // TypeError resolve(); }); (async () => { await p; })().catch(e => console.log("Caught: " + e)); // Catches it.
с наивным (неправильным)
async
эквивалентом:let p = new Promise(async resolve => { ""(); // TypeError resolve(); }); (async () => { await p; })().catch(e => console.log("Caught: " + e)); // Doesn't catch it!
Найдите последнюю версию в веб-консоли вашего браузера.
Первый работает, потому что любое немедленное исключение в функции-исполнителе конструктора Promise удобно отклоняет вновь созданное обещание (но внутри любого
.then
вы сами).Второй не работает, потому что любое немедленное исключение в
async
функции отклоняет неявное обещание, возвращаемое самойasync
функцией .Поскольку возвращаемое значение функции исполнителя конструктора обещаний не используется, это плохие новости!
Ваш код
Нет причин, по которым вы не можете определить
myFunction
какasync
:async function myFunction() { let array = await getAsyncArray(); return new Promise((resolve, reject) => { eachLimit(array, 500, (item, callback) => { // do other things that use native promises. }, error => { if (error) return reject(error); // resolve here passing the next value. }); }); }
Хотя зачем использовать устаревшие библиотеки управления параллелизмом, если они у вас есть
await
?источник
return await
:return new Promise
достаточно.Я согласен с приведенными выше ответами, и тем не менее, иногда лучше иметь асинхронность внутри вашего обещания, особенно если вы хотите связать несколько операций, возвращающих обещания, и избежать
then().then()
ада. Я бы подумал об использовании чего-то вроде этого в этой ситуации:const operation1 = Promise.resolve(5) const operation2 = Promise.resolve(15) const publishResult = () => Promise.reject(`Can't publish`) let p = new Promise((resolve, reject) => { (async () => { try { const op1 = await operation1; const op2 = await operation2; if (op2 == null) { throw new Error('Validation error'); } const res = op1 + op2; const result = await publishResult(res); resolve(result) } catch (err) { reject(err) } })() }); (async () => { await p; })().catch(e => console.log("Caught: " + e));
Promise
конструктору, не является асинхронной, поэтому линтеры не показывают ошибок.await
.Однако недостатком является то, что вы должны помнить о том, что
try/catch
его вставляли и прикреплялиreject
.источник
static getPosts(){ return new Promise( (resolve, reject) =>{ try { const res = axios.get(url); const data = res.data; resolve( data.map(post => ({ ...post, createdAt: new Date(post.createdAt) })) ) } catch (err) { reject(err); } }) }
удалите ожидание, и асинхронный режим решит эту проблему. потому что вы применили объект Promise, этого достаточно.
источник
axios.get(url)
работать так, как если бы он был вызван какawait axios.get(url)
?