javascript - 如何阻止事件循环直到完成运行异步任务

标签 javascript node.js asynchronous redis event-loop

假设我们有一个网络服务器接收 HTTP 请求并发回响应。它有很多端点,包括这个

/task 应该有一些异步任务,比如从 Redis 读取/写入,我想阻塞事件循环,直到这些任务完成。我知道这是不合理的,因为事件循环还需要继续工作以接收 Redis 的事件。所以我正在考虑将这个逻辑放在一个单独的脚本中并使用 child_process.spawnSync 来执行并等待它并阻止当前事件循环。这个解决方案可行,但我的问题是我的逻辑,异步任务比这个示例中提到的更复杂,它们依赖于当前脚本并且它们是框架的一部分,将它们分离到一个单独的脚本并不容易.有什么建议吗?

var express = require('express');
var app = express();
var redis = require('./redis');

// Block the event loop until finish doing some async tasks
app.get('/task', function(req, res) {

  // Block the event loop now
  redis.get('backup', function(error, backup) {

    // ...... Do some changes to the backup data

    redis.set('backup', backup, function(error, result) {

      // Unblock the event loop now
      res.send('I am done');

    });

  });

});

// To check if the event loop is really blocked
counter = 0;
setInterval(() => { console.log(counter++) }, 100);

app.listen(5000);

最佳答案

您应该考虑使用 async/await .您将不得不重新编写所有适用的代码以使用 Promises 或使用为您执行此操作的库。

您的主要功能可能如下所示;

(async function main(){
 try{

 await taskFunction();
 await backupGetFunction();
 await backupSetFunction();
  res.send('I am done');

 } catch (error){
  throw error;
 }; 

})();

一切都会按顺序执行,最后会按预期重新发送“我完成了”。

此解决方案背后的复杂性在于,任何依赖于 main 函数的函数都需要使用 promises 以保持流程异步。

例如,您的备份功能最初可能是;

function backupExample(){
 fs.copyFile('source.txt', 'destination.txt', (err) => {
  if (err) throw err;
 console.log('source.txt was copied to destination.txt');
});
}; 

当它必须转换成下面的形式才能与 async/await 一起工作时;

function backupExample(){
 return new Promise((resolve, reject) => {
 fs.copyFile('source.txt', 'destination.txt', (err) => {
  if (err) reject(err);
 resolve('source.txt was copied to destination.txt');
  });
 });
}; 

promises 充当主要 async/await 函数的指南,因此它知道异步函数何时完成。

关于javascript - 如何阻止事件循环直到完成运行异步任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46994508/

相关文章:

循环返回语句中的javascript递归不起作用

javascript - NodeJS 通过纬度/经度查找国家/地区

javascript - Node.js http 请求

javascript - 是否可以从 JavaScript 中的 "inner"范围获取值?

javascript - 无法从存在的 json 中获取值

asynchronous - 来自代理/邮箱处理器的一般回复?

c# - 等待任务不适用于 IEnumerable

c# - Task 返回异步方法的 ConditionalAttribute 的等价物

javascript - 这个 JavaScript 的作用是什么?

node.js node-mysql 查询不起作用