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

时间:2018-10-21 13:43:27

标签: javascript node.js

在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);
  }
}

2 个答案:

答案 0 :(得分:2)

另一种使用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);
  }
}

答案 1 :(得分:0)

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

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

您可以这样做:

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。所有Promise都会停止并等待所有Promise完成。

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

祝你好运!