最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

setInterval中的promise

IT培训 admin 7浏览 0评论

setInterval中的promise

我有这个例程函数在setInterval函数上每隔60000ms运行一次。在这个例程函数中,我遍历解析的JSON(db)上的所有用户名,并检查它们是否可通过promise(checkUsername)获得,这是一个网络请求。

但是,我很清楚这是一个糟糕的方法,因为承诺可能需要60多秒才能完成,而且我一直在收到ETIMEDOUT错误。但我只是不理解承诺和异步,足以想到一个解决方案。

什么是更好的方法呢? async / await适合吗?

function routine() { 
  db.users.forEach(userObj => {
   userObj.username.forEach(username => {
    checkUsername(username).then(hasUser => {
    if(!hasUser) {
      bot.sendMessage(userObj.chatId, `‼️ Username @${username} is now AVAILABLE ‼️`);
      removeName(username, userObj.chatId);

    }

    }).catch(err => { 
      console.log(err);

    })

    })
});
}
setInterval(routine, 120000);
回答如下:

我创建了一个可以运行的代码片段,它使用Promise.all以及async / await ES7来使代码更易于处理和理解。我也打算在网上找到一个真正的API端点,仅仅是为了一个完整的例子。

如果你想要那个选项,我还添加了一种方法来阻止超时。

// How often the timeout will run.
// Since the timeout is dependent on when all the requests finish, the timeout will run this many ms after all the requests finish.
var interval = 5000;

// This is what your db seems to resemble.
var db = {
  users: [{
      username: ['1']
    },
    {
      username: ['2']
    },
    {
      username: ['3']
    },
    {
      username: ['4']
    },
  ]
};

// This will hold the timeout function so you can cancel it at a later time.
var timeoutFn;

// Returns returns a single Promise that resolves when all of the promises it contains have resolved/rejected. It rejects with the first promise that rejects.
function routine() {
  console.log("-- Running routine function --");

  // Return an array of promises. Please see my comments at the bottom of this whole answer which questions db architecture with username being an array.
  // I'm also using map instead of forEach because map automatically returns and array.
  let promiseArray = db.users.map(userObj => {
    return Promise.all(userObj.username.map(username => {
      // This processUsername() function should do all the work related to the username. It helps to keep the routine function as clean as possible since there's already a lot happening in here.
      return processUsername(username);
    }));
  });

  // Returns an array of array of promises. This means that every single promise within each array (see above) has to resolve before the `then` runs. If any reject, `catch` will run instead.
  return Promise.all(promiseArray).then(() => {
    runRoutineAgain();
  }).catch((err) => {
    console.log('err:', err)
  });
}

// This will create a timeout and run routine after interval.
function runRoutineAgain() {
  timeoutFn = setTimeout(routine, interval);
}


// This async function returns a promise
async function processUsername(username) {
  // Make API call to get data
  console.log('Processing username for', username);

  // I'm using this free API endpoint online just for the sake of making a complete example. Obviously your API will be returning very different data.
  return await fetch(`https://jsonplaceholder.typicode/todos/${username}`)
    .then(response => response.json())
    .then((json) => {
      console.log(json);
      // This is where you can do your processing.
      // if(!hasUser) {
      //    bot.sendMessage(userObj.chatId, `‼️ Username @${username} is now AVAILABLE ‼️`);
      //    removeName(username, userObj.chatId);
      //  }
    });
}


function stopTimeout() {
  clearTimeout(timeoutFn);
}

routine();

setInterval中的promise

我有这个例程函数在setInterval函数上每隔60000ms运行一次。在这个例程函数中,我遍历解析的JSON(db)上的所有用户名,并检查它们是否可通过promise(checkUsername)获得,这是一个网络请求。

但是,我很清楚这是一个糟糕的方法,因为承诺可能需要60多秒才能完成,而且我一直在收到ETIMEDOUT错误。但我只是不理解承诺和异步,足以想到一个解决方案。

什么是更好的方法呢? async / await适合吗?

function routine() { 
  db.users.forEach(userObj => {
   userObj.username.forEach(username => {
    checkUsername(username).then(hasUser => {
    if(!hasUser) {
      bot.sendMessage(userObj.chatId, `‼️ Username @${username} is now AVAILABLE ‼️`);
      removeName(username, userObj.chatId);

    }

    }).catch(err => { 
      console.log(err);

    })

    })
});
}
setInterval(routine, 120000);
回答如下:

我创建了一个可以运行的代码片段,它使用Promise.all以及async / await ES7来使代码更易于处理和理解。我也打算在网上找到一个真正的API端点,仅仅是为了一个完整的例子。

如果你想要那个选项,我还添加了一种方法来阻止超时。

// How often the timeout will run.
// Since the timeout is dependent on when all the requests finish, the timeout will run this many ms after all the requests finish.
var interval = 5000;

// This is what your db seems to resemble.
var db = {
  users: [{
      username: ['1']
    },
    {
      username: ['2']
    },
    {
      username: ['3']
    },
    {
      username: ['4']
    },
  ]
};

// This will hold the timeout function so you can cancel it at a later time.
var timeoutFn;

// Returns returns a single Promise that resolves when all of the promises it contains have resolved/rejected. It rejects with the first promise that rejects.
function routine() {
  console.log("-- Running routine function --");

  // Return an array of promises. Please see my comments at the bottom of this whole answer which questions db architecture with username being an array.
  // I'm also using map instead of forEach because map automatically returns and array.
  let promiseArray = db.users.map(userObj => {
    return Promise.all(userObj.username.map(username => {
      // This processUsername() function should do all the work related to the username. It helps to keep the routine function as clean as possible since there's already a lot happening in here.
      return processUsername(username);
    }));
  });

  // Returns an array of array of promises. This means that every single promise within each array (see above) has to resolve before the `then` runs. If any reject, `catch` will run instead.
  return Promise.all(promiseArray).then(() => {
    runRoutineAgain();
  }).catch((err) => {
    console.log('err:', err)
  });
}

// This will create a timeout and run routine after interval.
function runRoutineAgain() {
  timeoutFn = setTimeout(routine, interval);
}


// This async function returns a promise
async function processUsername(username) {
  // Make API call to get data
  console.log('Processing username for', username);

  // I'm using this free API endpoint online just for the sake of making a complete example. Obviously your API will be returning very different data.
  return await fetch(`https://jsonplaceholder.typicode/todos/${username}`)
    .then(response => response.json())
    .then((json) => {
      console.log(json);
      // This is where you can do your processing.
      // if(!hasUser) {
      //    bot.sendMessage(userObj.chatId, `‼️ Username @${username} is now AVAILABLE ‼️`);
      //    removeName(username, userObj.chatId);
      //  }
    });
}


function stopTimeout() {
  clearTimeout(timeoutFn);
}

routine();

与本文相关的文章

发布评论

评论列表 (0)

  1. 暂无评论