繁体   English   中英

在forEach循环完成后运行回调函数

[英]run a callback function after forEach loop finish

如何使用相同的代码在forEach循环完成后回调timer()函数。 还是有更好的方法来延迟每个用户的循环,然后在循环完成之后,使用forEach调用timer()。

  const usersProfile = () => {
  let interval = 1000;
  let promise = Promise.resolve();
  db.select('*').from('users')
    .returning('*')
    .then(users => {
      users.forEach((user, index) => {
        setTimeout(function(){

        }, index * 1000)
        db.select('*').from(`${user.name}`)
          .returning('*')
          .then(userdata => {
            userdata.forEach(data => {
                promise = promise.then(function(){
                  if(data.status === 'online'){
                    console.log(`${data.name} ${data.items} ${data.profile} ${data.images}`)
                  }
                return new Promise(function(resolve){
                    setTimeout(function(){
                      resolve();
                    }, interval)
                })
              })
            })
          })
      })
       timer();
    })
}
const timer = () => {
  setTimeout(usersProfile, 1000)
}
timer();

=============以上都是我的旧代码=================但要感谢https://stackoverflow.com/users / 2404452 / tho-vu它解决了大多数问题,但是我可以这样做来满足应用程序的目的

const usersProfile = async () => {
  let interval = 1000;

  const delayPromise = (data, delayDuration) => {
    return new Promise((resolve) => {
      setTimeout(() => {
        if(data.status === 'online'){
          console.log(`${data.name} ${data.items} ${data.profile} ${data.images}`);
          resolve();
        }
      }, delayDuration)
    });
  };

 const userInfo = (data, delayDuration) => {
    return new Promise((resolve) => {
      setTimeout(() => {
          console.log(`${data.info}`);//info about user from his table each user has his own table besides users table that has only the user tables
          resolve();
      }, delayDuration)
    });
  };
  try {
    const userData = await db.select('*').from('users').returning('*');
    const promises = userData.map((data, index) => delayPromise(data, index * interval));
    const userData = await db.select('*').from(`${data.name}`).returning('*');
    const info = userData.map((data, index) => userInfo(data, index * interval));
    await Promise.all(promises);
    // here you can write your effects
  } catch (e) {
    console.log(e);
  }
}

另一种使用async-await避免回调地狱的方法。

const usersProfile = async () => {
  let interval = 1000;

  const delayPromise = (data, delayDuration) => {
    return new Promise((resolve) => {
      setTimeout(() => {
        if(data.status === 'online'){
          console.log(`${data.name} ${data.items} ${data.profile} ${data.images}`);
          resolve();
        }
      }, delayDuration)
    });
  };

  try {
    const userData = await db.select('*').from('users').returning('*');
    const promises = userData.map((data, index) => delayPromise(data, index * interval));
    await Promise.all(promises);
    // here you can write your effects
  } catch (e) {
    console.log(e);
  }
}

我很难完全理解您想要通过代码完成的工作,但是我将尽力解释可以解决该问题的方法。

首先,如果要等待多个promise,则应使用Promise.all而不是promise = promise.then Promise.all

您可以这样做:

let promises = [];
users.forEach((user, index) => {
   let promise = db.select(*).from('users') //should return a promise
   promises.push(promise);
});

//promises have already started to execute (in parallel)

Promise.all(promises)
.then(() => console.log('all promises finished successfully'))
.catch((e) => console.error('received error at one of the promises'));


 // when the program arrives here we know for a fact that either all promises executed successfully or one of the promises failed

timer();

说明:由于诺言异步执行,因此forEach()函数不会等待任何创建的诺言完成,因此解决方案是在整个循环之后再等待所有诺言。

这意味着在forEach()循环并行执行时以及程序到达Promise时,将创建并执行这些Promise.All停止并等待所有Promise完成。

其次,我强烈建议您使用函数来简化代码,那样一来,即使它很复杂,您也可以更轻松地掌握所有正在发生的事情。

祝好运 !

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM