javascriptnode.jsexpressjsdiff

Stopping slow jsdiff function after 2 seconds


I'm using the npm library jsdiff, which has a function that determines the difference between two strings. This is a synchronous function, but given two large, very different strings, it will take extremely long periods of time to compute.

diff = jsdiff.diffWords(article[revision_comparison.field], content[revision_comparison.comparison]);

This function is called in a stack that handles an request through Express. How can I, for the sake of the user, make the experience more bearable? I think my two options are:

  1. Cancelling the synchronous function somehow.
  2. Cancelling the user request somehow. (But would this keep the function still running?)

Edit: I should note that given two very large and different strings, I want a different logic to take place in the code. Therefore, simply waiting for the process to finish is unnecessary and cumbersome on the load - I definitely don't want it to run for any long period of time.


Solution

  • I found this on jsdiff's repository:

    All methods above which accept the optional callback method will run in sync mode when that parameter is omitted and in async mode when supplied. This allows for larger diffs without blocking the event loop. This may be passed either directly as the final parameter or as the callback field in the options object.

    This means that you should be able to add a callback as the last parameter, making the function asynchronous. It will look something like this:

      jsdiff.diffWords(article[x], content[y], function(err, diff) {
        //add whatever you need
      });
    

    Now, you have several choices:

    1. Return directly to the user and keep the function running in the background.

    2. Set a 2 second timeout (or whatever limit fits your application) using setTimeout as outlined in this answer.

    If you go with option 2, your code should look something like this

      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);