У меня есть функция, которая содержит обещание, содержащее функцию setTimeout. Функция set timeout проходит через вызов axios, который распределяет вызовы, чтобы избежать ошибки ограничения скорости. Это прекрасно работает, хотя и немного медленно. То, что я хотел бы сделать, это перенаправить после того, как все звонки были завершены. Я устанавливаю остаток равным последнему возвращенному элементу. Где я смущен тем, как сравнить это с массивом массивов в цикле foreach. Будет ли лучшим подходом здесь создать новый массив возвращаемых индексов, отвечающих условию if? Любая обратная связь будет принята с благодарностью?
Я пытался создать новый массив на основе значения и индекса, но я немного заржавел в том, как это сделать правильно внутри условия if.
async function axiosRequest() {
let newT = {
value: {
test: 't',
test2: 't2',
test3: 't3',
test4: 't4',
test5: '',
test6: ''
}
}
let contianerT = [];
const promise = new Promise((resolve, reject) => {
for (let m in contianerT) {
let remainder = Object.keys(contianerT[m].value).length
Object.entries(contianerT[m].value).forEach(([key, value], index, array) => {
let newArray = [];
if (value !== "") { //don't loop through empty values
// let len = Object.keys(value).length
//let last_element = sortedKeys[sortedKeys.length - 1];
setTimeout(() => {
remainder--;
//axios.post('/url',{key: key, value: value}) lives here
// len --;
console.info(remainder)
//console.info(len)
//console.info(index)
if (remainder === index) {
resolve();
}
}, 500 * index);
}
});
}
});
await promise
}
axiosRequest()
.then(() => {
console.info('redirect')
})
Результат должен проходить через длину объектов и возвращать функцию разрешения, если последние элементы совпадают (если они достигли конца)
@jfriend00 извините за то, что я почистил его
Где собственно асинхронная операция в этом коде? Я не вижу ни одного.
Есть намного, гораздо лучшие способы избежать ограничения скорости, чем просто заранее запланировать весь цикл событий с помощью таймеров с задержкой. Кроме того, это разрушает ваш контроль, когда у вас есть все эти вещи, запланированные с помощью таймеров. Мы сможем помочь вам лучше, если вы покажете нам реальную асинхронную операцию, которую вы пытаетесь выполнить, и объясните фактические ограничения скорости, которым вы должны следовать.
@ jfriend00 Я убрал его для простоты - он просто принимает ключ и значение, возвращаемое в цикле. Я просто смотрю, как я могу добраться до метода разрешения. Обычно остаток === 0 имел бы здесь смысл, но поскольку пустые значения не применяются, остаток не всегда будет равен 0. Я думаю, чтобы решить эту проблему. Возможно, имеет смысл создать объект, независимый от пустых значений, а затем перейти к циклу Это?
@ jfriend00 спасибо, я вызываю запрос внутри setTimeout. Фактический код настроен в службе, поэтому здесь это не имеет смысла, он просто выглядит как ваш стандартный почтовый запрос. Я пытался использовать axios-rate-limit в почтовом запросе, но обнаружил, что он не работает с перенаправлением, поэтому я нашел этот метод. Ограничение скорости — 40 запросов за 1000 мс.
Все еще пытаетесь понять, чего вы пытаетесь достичь? Что означает это «как сравнить это с массивом массивов в цикле foreach»? В одной части вопроса кажется, что вы просто пытаетесь избежать ограничения скорости и знаете, когда все запросы выполняются. В другой части вопроса вы спрашиваете о сравнении массива массивов, о котором я понятия не имею, что это такое. Извините, но я не могу точно сказать, в чем вам нужна помощь?
Извините за путаницу. Я пытался установить масштаб проблемы. Основная проблема заключается в том, что я не уверен, как достичь метода разрешения, чтобы перейти к перенаправлению после того, как последний элемент в цикле был достигнут в методе axiosRequest (после того, как seTimout достиг последнего индекса)
Судя по вашим комментариям, вы просто пытаетесь понять, как узнать, когда выполнен последний запрос. Для этого я бы предложил просто поместить все промисы в массив и использовать Promise.all()
для массива промисов, чтобы узнать, когда они все будут выполнены. Таким образом, Promise.all()
сделает за вас всю работу по поддержанию счетчиков, чтобы знать, когда все запросы будут выполнены.
Я также заменил ваше использование setTimeout()
служебной функцией на основе промисов delay()
, которая лучше сочетается с промисами.
// helper function that returns a promise
// that resolves after a timeout time
function delay(t, v) {
return new Promise(resolve => {
setTimeout(() => {
resolve(v);
}, t);
});
}
function axiosRequest() {
let newT = {
value: {
test: 't',
test2: 't2',
test3: 't3',
test4: 't4',
test5: '',
test6: ''
}
}
let promises = [];
let contianerT = [];
for (let m of contianerT) {
Object.entries(contianerT[m].value).forEach(([key, value], index, array) => {
if (value !== "") { //don't loop through empty values
// let len = Object.keys(value).length
//let last_element = sortedKeys[sortedKeys.length - 1];
promises.push(delay(500 * index).then(() =>
return axios.post('/url',{key: key, value: value}); // I assume this returns a promise
}));
}
});
}
// returns a promise that resolves to an array of axios.post() results
return Promise.all(promises);
}
axiosRequest().then(() => {
console.info('redirect');
});
Примечания:
Я предположил, что axios.post()
возвращает обещание, которое разрешается в возвращаемое значение.
Я не пытался переписать/исправить вашу задержку, чтобы обойти ограничение скорости. То, что у вас есть, очень примитивно и, вероятно, будет недостаточно, если contianerT
— большой массив.
Массивы должны повторяться с помощью for/of
, а не for/in
, потому что for/in
перебирает свойства объекта, а не элементы массива. Итак, for (let m in contianerT)
выглядит неправильно. Также обратите внимание, что большинство людей пишут это слово как «контейнер».
P.S. Обычно я даже не задаюсь вопросами, которые содержат преимущественно псевдокод, потому что часто спрашивающий даже не знает всех проблем, о которых нужно спросить, или задает неправильный вопрос, и мы можем гораздо точнее предложить ответ. лучший ответ, когда мы сможем увидеть настоящий код. Пожалуйста, опубликуйте свой РЕАЛЬНЫЙ код в следующий раз. Вы будете приятно удивлены, насколько лучшие люди могут помочь вам и насколько больше помощи вы получите в вещах, о которых вы даже не подозревали, что есть лучший способ.
спасибо за отзыв и обнаружение опечатки. Я не могу предоставить все файлы в настоящее время, однако то, что у меня есть, это компиляция, поэтому я бы не назвал это псевдокодом, но в следующий раз я буду более краток. Я не могу скомпилировать предоставленный вами фрагмент, но я понимаю логику использования задержки, а затем возврата Promise.all, поэтому я поработаю над тем, чтобы это работало.
@BluLotus - Какую ошибку вы получаете? Возможно, в моем ответе опечатка, но вы должны получить общее представление, верно?
@BluLotus - я исправил опечатку.
Было бы полезно, если бы в вашем коде был правильный отступ.