Javascript 如何在完成异步任务之前阻止事件循环
假设我们有一个web服务器,它接收http请求并发送响应。它有许多端点,包括这个端点Javascript 如何在完成异步任务之前阻止事件循环,javascript,node.js,asynchronous,redis,event-loop,Javascript,Node.js,Asynchronous,Redis,Event Loop,假设我们有一个web服务器,它接收http请求并发送响应。它有许多端点,包括这个端点 /task应该有一些异步任务,比如从Redis读取/写入,我想阻止事件循环,直到这些任务完成。我知道这是不合理的,因为事件循环还需要继续工作以接收Redis的事件。因此,我正在考虑将此逻辑放在一个单独的脚本中,并使用child\u process.spawnSync执行并等待它并阻止当前事件循环。这个解决方案会起作用,但我的问题是我的逻辑和异步任务比本示例中提到的更复杂,它们与当前脚本有依赖关系,并且它们是框架
/task
应该有一些异步任务,比如从Redis
读取/写入,我想阻止事件循环,直到这些任务完成。我知道这是不合理的,因为事件循环还需要继续工作以接收Redis
的事件。因此,我正在考虑将此逻辑放在一个单独的脚本中,并使用child\u 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);
你应该研究一下如何使用它。您必须重新编写所有适用的代码才能使用Promissions或使用为您这样做的库 您的主要功能可能如下所示:
(async function main(){
try{
await taskFunction();
await backupGetFunction();
await backupSetFunction();
res.send('I am done');
} catch (error){
throw error;
};
})();
一切都将按顺序执行,最后,它将按预期发送“我完成了”
此解决方案背后的复杂性在于,任何依赖于主函数的函数都需要使用承诺来保持流异步
例如,您的备份功能最初可能是:
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');
});
});
};
承诺作为主要异步/等待函数的指南,以便它知道异步函数何时完成。您应该研究如何使用。您必须重新编写所有适用的代码才能使用Promissions或使用为您这样做的库 您的主要功能可能如下所示:
(async function main(){
try{
await taskFunction();
await backupGetFunction();
await backupSetFunction();
res.send('I am done');
} catch (error){
throw error;
};
})();
一切都将按顺序执行,最后,它将按预期发送“我完成了”
此解决方案背后的复杂性在于,任何依赖于主函数的函数都需要使用承诺来保持流异步
例如,您的备份功能最初可能是:
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');
});
});
};
承诺作为主要异步/等待函数的指南,以便它知道异步函数何时完成。您可以使用
redis.getAsync('backup')
.then(res => {
// ...... Do some changes to the backup data
return redis.set('backup', backup)
})
.then(()=>res.send('I\'m done'))
或
注意:如果使用异步/等待功能,则至少需要有节点v7及以上。或者——运行您可以使用的节点时的harmony async Wait标志
redis.getAsync('backup')
.then(res => {
// ...... Do some changes to the backup data
return redis.set('backup', backup)
})
.then(()=>res.send('I\'m done'))
或
注意:如果使用异步/等待功能,则至少需要有节点v7及以上。或者——运行节点时使用harmony async Wait标志
有什么建议吗?
,有。不要堵住。不清楚为什么在你的描述中你也需要1.我为什么需要阻止并不重要,问题是如何阻止。无论如何,我需要将一些会话状态备份到Redis中,并防止接收到可能使这些数据无效的事件,直到将当前会话状态存储到Redis中,然后继续处理其间接收到的事件,这就是为什么我需要阻止事件循环,让那些事件排队并防止竞争条件。你可以在不阻塞主线程的情况下完成所有这些。不管怎么说,你有什么建议,那是我的。如果这是一个多用户网站,这样做会使它瘫痪。我不认为阻止事件循环也是一种选择。也许升起一面全球旗帜或使用其他机制对你有用。例如,//立即阻止事件循环
->global.event\u loop\u BLOCKED=true
。现在使用此变量返回类似“服务器当前正忙”的内容,响应与Redis交互的所有请求,当您完成作业时,只需global.EVENT\u LOOP\u BLOCKED=false
那么,node.js中没有好的解决方案来自于阻止事件循环,因此,你应该告诉我们你试图解决的真正问题,然后我们可以帮助你更好地找到一个好的解决方案。这里是一个XY问题,您只是用解决方案描述了一个问题,但该解决方案是一条死胡同,因为您没有描述实际问题,我们无法帮助您。有什么建议吗?
,是的。不要堵住。不清楚为什么在你的描述中你也需要1.我为什么需要阻止并不重要,问题是如何阻止。无论如何,我需要将一些会话状态备份到Redis中,并防止接收到可能使这些数据无效的事件,直到将当前会话状态存储到Redis中,然后继续处理其间接收到的事件,这就是为什么我需要阻止事件循环,让那些事件排队并防止竞争条件。你可以在不阻塞主线程的情况下完成所有这些。不管怎么说,你有什么建议,那是我的。如果这是一个多用户网站,这样做会使它瘫痪。我不认为阻止事件循环也是一种选择。也许升起一面全球旗帜或使用其他机制对你有用。例如,//立即阻止事件循环
->global.event\u loop\u BLOCKED=true
。现在使用此变量返回类似“服务器当前正忙”的内容,响应与Redis交互的所有请求,当您完成作业时,只需global.EVENT\u LOOP\u BLOCKED=false
那么,node.js中没有好的解决方案来自于阻止事件循环,因此,你应该告诉我们你试图解决的真正问题,然后我们可以帮助你更好地找到一个好的解决方案。这里是一个XY问题,您只是用解决方案描述了一个问题,但该解决方案是一条死胡同,因为您没有描述实际问题,我们无法帮助您。根据您的请求进行更新,egon12.我认为async函数备份示例
不需要async
关键字,因为它已经返回Promise
。根据您的请求更新,egon12。我认为async函数备份示例
不需要