Maison >interface Web >js tutoriel >Une brève discussion sur la façon d'implémenter une file d'attente de tâches asynchrone à l'aide de la méthode de blocage JS ?

Une brève discussion sur la façon d'implémenter une file d'attente de tâches asynchrone à l'aide de la méthode de blocage JS ?

青灯夜游
青灯夜游avant
2021-08-23 11:17:302165parcourir

Comment implémenter une file d'attente de tâches asynchrone à l'aide de JavaScript et traiter toutes les tâches de la file d'attente dans l'ordre ? Cet article vous présentera comment implémenter une file d'attente de tâches asynchrone à l'aide de la méthode de blocage JavaScript.

Une brève discussion sur la façon d'implémenter une file d'attente de tâches asynchrone à l'aide de la méthode de blocage JS ?

Question

Il est nécessaire de mettre en œuvre une file d'attente de tâches asynchrone et de traiter toutes les tâches de la file d'attente dans l'ordre, comme suit :

  • Ajouter des tâches asynchrones à la file d'attente à des moments aléatoires

  • File d'attente Les tâches sont exécutées séquentiellement selon la règle du premier entré, premier sorti

  • Les tâches sont des requêtes asynchrones. Attendez qu'une exécution soit terminée avant d'exécuter la suivante

Cette exigence est facile à mettre en œuvre. en utilisant BlockingQueue en langage Java, mais JavaScript n'a pas de mécanisme de verrouillage ce n'est pas si simple à mettre en œuvre.

Option 1

Il est facile de penser à utiliser le schéma synchrone non bloquant pour vérifier s'il y a des tâches dans la file d'attente à certains intervalles, et s'il y a des tâches, retirez la première pour le traitement . L'intervalle de détection ici est de 500 millisecondes et setTimeout est utilisé pour simuler des requêtes asynchrones.

<body>
  <button onclick="clickMe()">点我</button>
</body>
let queue = []
let index = 0
function clickMe() {
  queue.push({name: &#39;click&#39;, index: index++})
}

run()
async function run() {
  while (true) {
    if (queue.length > 0) {
      let obj = queue.shift()
      let res = await request(obj.index)
      console.log(&#39;已处理事件&#39; + res)
    } else {
      await wait(500)
      console.log(&#39;----- 队列空闲中 -----&#39;)
    }
  }
}
// 通过setTimeout模拟异步请求
function request(index) {
  return new Promise(function (resolve, reject) {
    setTimeout(() => {
      resolve(index)
    }, 1000)
  })
}
function wait(time) {
  return new Promise(function (resolve) {
    setTimeout(() => {
      resolve()
    }, time)
  })
}

Une brève discussion sur la façon dimplémenter une file dattente de tâches asynchrone à laide de la méthode de blocage JS ?

Mais il y a 2 problèmes avec cette solution.

  • La file d'attente inactive est toujours traitée en boucle, consommant des ressources
  • L'intervalle de détection est difficile à comprendre. Si l'intervalle est trop long, la tâche de file d'attente ne peut pas être traitée et l'intervalle de détection est trop court, ce qui consomme. resources

Est-ce comme BlockingQueue en Java ? Qu'en est-il d'un moyen de bloquer lorsque la file d'attente est inactive et de ne pas consommer de ressources ?

Option 2

Idée principale :

  • Ajouter des requêtes asynchrones à la file d'attente Lorsque le nombre de tâches dans la file d'attente est supérieur à 0, commencez à traiter les tâches dans la file d'attente
  • Attendez qu'une tâche soit exécutée avant. exécuter la tâche suivante
  • Une fois toutes les tâches de la file d'attente traitées, l'état d'exécution est marqué comme faux
<body>
<button onclick="clickMe()">点我</button>
</body>
// 异步请求队列
const queue = []
// 用来模拟不同的返回值
let index = 0
// 标志是否正在处理队列中的请求
let running = false

// 使用setTimeout模拟异步请求
function request(index) {
  return new Promise(function (resolve) {
    setTimeout(() => {
      resolve(index)
    }, 1000)
  })
}

// 连续点击,触发异步请求,加入任务队列
function clickMe() {
  addQueue(() => request(index++))
}

// 当队列中任务数大于0时,开始处理队列中的任务
function addQueue(item) {
  queue.push(item)
  if (queue.length > 0 && !running) {
    running = true
    process()
  }
}

function process() {
  const item = queue.shift()
  if (item) {
    item().then(res => {
      console.log(&#39;已处理事件&#39; + res)
      process()
    })
  } else {
    running = false
  }
}

Une brève discussion sur la façon dimplémenter une file dattente de tâches asynchrone à laide de la méthode de blocage JS ?

Conclusion

En utilisant la fonctionnalité de Promesse qu'il bloquera toujours sans résolution, vous pouvez obtenez une fonction similaire à BlockingQueue de Java, et les tâches asynchrones sont exécutées en séquence et la file d'attente ne consomme pas de ressources lorsqu'elle est inactive.

Pour plus de connaissances sur la programmation, veuillez visiter : Vidéos de programmation ! !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer