我正在使用npm库jsdiff,它有一个确定两个字符串之间差异的函数。这是一个同步函数,但是如果给出两个非常不同的大字符串,则需要很长的时间来计算。
diff = jsdiff.diffWords(article[revision_comparison.field], content[revision_comparison.comparison]);
在通过Express处理请求的堆栈中调用此函数。为了用户的缘故,我怎样才能让体验变得更加可忍受?我认为我的两个选择是:
编辑:我应该注意,给定两个非常大且不同的字符串,我想在代码中发生不同的逻辑。因此,简单地等待过程完成是不必要的并且在负载上很麻烦 - 我绝对不希望它在很长一段时间内运行。
答案 0 :(得分:2)
fork a child process对于该特定任务,您甚至可以创建一个队列来限制在给定时刻可以运行的子进程数。
在这里,您有一个工作人员的基本示例,该工作人员将原始快速req
和res
发送给执行大量同步的子项。不阻塞主(主)线程的操作,一旦完成,就会返回主控结果。
工作人员(分叉示例):
process.on('message', function(req,res) {
/* > Your jsdiff logic goes here */
//change this for your heavy synchronous :
var input = req.params.input;
var outcome = false;
if(input=='testlongerstring'){outcome = true;}
// Pass results back to parent process :
process.send(req,res,outcome);
});
来自大师:
var cp = require('child_process');
var child = cp.fork(__dirname+'/worker.js');
child.on('message', function(req,res,outcome) {
// Receive results from child process
console.log('received: ' + outcome);
res.send(outcome); // end response with data
});
你可以完美地向孩子发送一些工作以及req
和res
这样的(来自大师):(想象app = express)
app.get('/stringCheck/:input',function(req,res){
child.send(req,res);
});
答案 1 :(得分:1)
我在jsdiff's repository上找到了这个:
上述所有接受可选回调方法的方法将在省略该参数时以同步模式运行,并在提供时以异步模式运行。这允许更大的差异而不阻塞事件循环。这可以直接作为最终参数传递,也可以作为选项对象中的回调字段传递。
这意味着您应该能够将回调添加为最后一个参数,从而使该函数异步。它看起来像这样:
jsdiff.diffWords(article[x], content[y], function(err, diff) {
//add whatever you need
});
现在,您有几种选择:
直接返回给用户并使该功能在后台运行。
使用setTimeout设置2秒超时(或适合您应用的任何限制),如下所述 answer
如果你选择选项2,你的代码看起来应该是这样的
jsdiff.diffWords(article[x], content[y], function(err, diff) {
//add whatever you need
return callback(err, diff);
});
//if this was called, it means that the above operation took more than 2000ms (2 seconds)
setTimeout(function() { return callback(); }, 2000);