Как я могу вызвать разрешение в промисе при циклическом просмотре объекта, который соответствует только определенным условиям?

У меня есть функция, которая содержит обещание, содержащее функцию 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 21.06.2019 00:05

@jfriend00 извините за то, что я почистил его

BluLotus 21.06.2019 00:11

Где собственно асинхронная операция в этом коде? Я не вижу ни одного.

jfriend00 21.06.2019 00:45

Есть намного, гораздо лучшие способы избежать ограничения скорости, чем просто заранее запланировать весь цикл событий с помощью таймеров с задержкой. Кроме того, это разрушает ваш контроль, когда у вас есть все эти вещи, запланированные с помощью таймеров. Мы сможем помочь вам лучше, если вы покажете нам реальную асинхронную операцию, которую вы пытаетесь выполнить, и объясните фактические ограничения скорости, которым вы должны следовать.

jfriend00 21.06.2019 00:52

@ jfriend00 Я убрал его для простоты - он просто принимает ключ и значение, возвращаемое в цикле. Я просто смотрю, как я могу добраться до метода разрешения. Обычно остаток === 0 имел бы здесь смысл, но поскольку пустые значения не применяются, остаток не всегда будет равен 0. Я думаю, чтобы решить эту проблему. Возможно, имеет смысл создать объект, независимый от пустых значений, а затем перейти к циклу Это?

BluLotus 21.06.2019 00:53

@ jfriend00 спасибо, я вызываю запрос внутри setTimeout. Фактический код настроен в службе, поэтому здесь это не имеет смысла, он просто выглядит как ваш стандартный почтовый запрос. Я пытался использовать axios-rate-limit в почтовом запросе, но обнаружил, что он не работает с перенаправлением, поэтому я нашел этот метод. Ограничение скорости — 40 запросов за 1000 мс.

BluLotus 21.06.2019 01:01

Все еще пытаетесь понять, чего вы пытаетесь достичь? Что означает это «как сравнить это с массивом массивов в цикле foreach»? В одной части вопроса кажется, что вы просто пытаетесь избежать ограничения скорости и знаете, когда все запросы выполняются. В другой части вопроса вы спрашиваете о сравнении массива массивов, о котором я понятия не имею, что это такое. Извините, но я не могу точно сказать, в чем вам нужна помощь?

jfriend00 21.06.2019 01:04

Извините за путаницу. Я пытался установить масштаб проблемы. Основная проблема заключается в том, что я не уверен, как достичь метода разрешения, чтобы перейти к перенаправлению после того, как последний элемент в цикле был достигнут в методе axiosRequest (после того, как seTimout достиг последнего индекса)

BluLotus 21.06.2019 01:08
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
0
8
26
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Судя по вашим комментариям, вы просто пытаетесь понять, как узнать, когда выполнен последний запрос. Для этого я бы предложил просто поместить все промисы в массив и использовать 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');
});

Примечания:

  1. Я предположил, что axios.post() возвращает обещание, которое разрешается в возвращаемое значение.

  2. Я не пытался переписать/исправить вашу задержку, чтобы обойти ограничение скорости. То, что у вас есть, очень примитивно и, вероятно, будет недостаточно, если contianerT — большой массив.

  3. Массивы должны повторяться с помощью for/of, а не for/in, потому что for/in перебирает свойства объекта, а не элементы массива. Итак, for (let m in contianerT) выглядит неправильно. Также обратите внимание, что большинство людей пишут это слово как «контейнер».

P.S. Обычно я даже не задаюсь вопросами, которые содержат преимущественно псевдокод, потому что часто спрашивающий даже не знает всех проблем, о которых нужно спросить, или задает неправильный вопрос, и мы можем гораздо точнее предложить ответ. лучший ответ, когда мы сможем увидеть настоящий код. Пожалуйста, опубликуйте свой РЕАЛЬНЫЙ код в следующий раз. Вы будете приятно удивлены, насколько лучшие люди могут помочь вам и насколько больше помощи вы получите в вещах, о которых вы даже не подозревали, что есть лучший способ.

спасибо за отзыв и обнаружение опечатки. Я не могу предоставить все файлы в настоящее время, однако то, что у меня есть, это компиляция, поэтому я бы не назвал это псевдокодом, но в следующий раз я буду более краток. Я не могу скомпилировать предоставленный вами фрагмент, но я понимаю логику использования задержки, а затем возврата Promise.all, поэтому я поработаю над тем, чтобы это работало.

BluLotus 21.06.2019 02:54

@BluLotus - Какую ошибку вы получаете? Возможно, в моем ответе опечатка, но вы должны получить общее представление, верно?

jfriend00 21.06.2019 03:10

@BluLotus - я исправил опечатку.

jfriend00 21.06.2019 03:11

Другие вопросы по теме