JSFiddle - React, Tailwind, and code Playground

JavaScript

var PromiseWorker = function (fn) {
    var FnToWorker = function (fn) {
        var workerBody = "self.addEventListener('message'," +
            "function (d) {" +
            "var result;" +
            "try {" +
            "result = (" + fn.toString() + ")(d.data.Data);" +
            "self.postMessage({ Result: result, Id: d.data.Id });" +
            "} catch (e) {" +
            "self.postMessage({ Error: e, Id: d.data.Id });" +
            "}" +
            "});"
        var worker = new Worker(URL.createObjectURL(new Blob([workerBody])));
        return worker;
    }
    var promises = []; //Очередь вызовов
    var Invoke = function (data) {
        var message = { Data: data, Id: performance.now() }; //У каждого сообщения Id, чтобы ничего не путалось
        var p = new Promise(function (resolve, reject) {
            promises[message.Id] = { resolve: resolve, reject: reject };
        });
        worker.postMessage(message); //Запускаем воркер
        return p;
    }
    var OnMessage = function (data) {
        if (data.data.Error) {
            promises[data.data.Id].reject(data.data.Result);
        } else {
            promises[data.data.Id].resolve(data.data.Result);
        }
        promises[data.data.Id] = undefined;
    }
    var worker = FnToWorker(fn);
    worker.addEventListener('message', OnMessage);
    return {
        Invoke: Invoke
    }
}
new PromiseWorker(function (array) {
    return array.sort();
}).Invoke([3, 2, 1]).then(function (result) {
    alert(result)
});