代码之家  ›  专栏  ›  技术社区  ›  The pyramid

foreach循环完成后运行回调函数

  •  0
  • The pyramid  · 技术社区  · 6 年前

    如何在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 回复  |  直到 6 年前
        1
  •  1
  •   blaz    6 年前

    另一种方法使用 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);
      }
    }
    
        2
  •  0
  •   orpris12    6 年前

    我很难完全理解您希望通过代码实现什么,但是我将尝试解释您可以做些什么来解决这个问题。

    首先,如果你想等待多个承诺,你应该使用 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();
    

    解释:因为promises是异步执行的,foreach()函数不等待创建的任何promises完成,所以解决方案是在整个循环之后等待所有的promises完成。

    这意味着当foreach()循环并行执行时,以及当程序达到promise时,将创建并执行承诺。所有这些承诺都将停止并等待所有承诺完成。

    第二,我强烈建议您使用函数作为简化代码的一种方法,这样您就更容易掌握正在发生的每一件事情,即使它很复杂。

    祝你好运!