在遍历仅满足特定条件的对象时,如何在承诺中调用 resolve?

How can I call resolve in a promise while looping through an object that only meets certain conditions?

我有一个包含 setTimeout 函数的承诺的函数。设置超时函数通过 axios 调用循环,该调用分散调用以避免速率限制错误。这很好用,尽管有点慢。我想做的是在所有呼叫完成后重定向。我将余数设置为等于最后一个元素 returned。我对如何将其与 foreach 循环中的数组进行比较感到困惑。这里最好的方法是创建一个满足 if 条件的索引 returned 的新数组吗?任何反馈将不胜感激?

我已经尝试根据值和索引创建一个新数组,但我对如何在 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.log(remainder)
                       //console.log(len)
                       //console.log(index)
                       if (remainder === index) {
                           resolve();
                       }

                   }, 500 * index);
               }
           });
       }
   });
   await promise
}
axiosRequest()
   .then(() => {
       console.log('redirect')
   })

如果最后一个元素匹配(如果它们已到达末尾),结果应该遍历对象的长度和 return 解析函数

从您的评论来看,您似乎只是想弄清楚如何知道最后一个请求何时完成。为此,我建议将所有承诺推入一个数组,并在承诺数组上使用 Promise.all() 以了解它们何时全部完成。这样 Promise.all() 会为您完成维护计数器的所有工作,以了解所有请求何时完成。

我还用 promise-based 效用函数 delay() 替换了你对 setTimeout() 的使用,它与 promises 的混合效果更好。

// 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.log('redirect');
});

备注:

  1. 我假设 axios.post() returns 一个解析为它的返回值的承诺。

  2. 我没有试图 rewrite/fix 你的延迟来绕过速率限制。你拥有的是非常原始的,如果 contianerT 是一个大数组,可能还不够。

  3. 数组应该用 for/of 迭代,而不是 for/in,因为 for/in 迭代对象属性,而不是数组元素。所以,for (let m in contianerT) 看起来不正确。另请注意,大多数人拼写为 "container".

P.S。通常,我什至不参与主要是 pseudo-code 的问题,因为发问者通常甚至不知道要问的所有问题或者没有问正确的问题,我们可以更准确地当我们能看到真正的代码时,提供最佳答案。下次请 post 您的真实代码。你会惊喜地发现有更好的人可以帮助你,你会得到更多的帮助来完成你甚至不知道有更好的方法来完成的事情。