How run async / await in parallel in Javascript

后端 未结 6 976
没有蜡笔的小新
没有蜡笔的小新 2020-11-30 17:16

Finally async/await will be supported in all major browser soon except IE. So now we can start writing more readable code with async/<

6条回答
  •  春和景丽
    2020-11-30 18:09

    First, are your code a blocking-code?

    If yes, remember that javascript is single thread, so you cannot run two synchronous codes, for example two loops (for or while) at the same time.

    But, it is possible to achieve that using Web Workers, I managed to execute functions in generic web workers and without using separated js files.

    setInterval(()=>{console.log("non blocked " + Math.random())}, 900)
    
    console.log("start blocking code in parallel in web Worker")
    console.time("blocked")
    
    genericWorker(window, ["blockCpu", function (block){    
        block(10000) //This blockCpu function is defined below
        return "\n\nbla bla\n" //This is catched in the resolved promise
    
    }]).then(function (result){
        console.timeEnd("blocked")
        console.log("End of blocking code", result)
    })
    .catch(function(error) { console.log(error) })
    
    
    /*  A Web Worker that does not use a File, it create that from a Blob
        @cb_context, The context where the callback functions arguments are, ex: window
        @cb, ["fn_name1", "fn_name2", function (fn1, fn2) {}]
            The callback will be executed, and you can pass other functions to that cb
    */
    function genericWorker(cb_context, cb) {
        return new Promise(function (resolve, reject) {
    
            if (!cb || !Array.isArray(cb))
                return reject("Invalid data")
    
            var callback = cb.pop()
            var functions = cb
    
            if (typeof callback != "function" || functions.some((fn)=>{return typeof cb_context[fn] != "function"}))
                return reject(`The callback or some of the parameters: (${functions.toString()}) are not functions`)
    
            if (functions.length>0 && !cb_context)
                return reject("context is undefined")
    
            callback = fn_string(callback) //Callback to be executed
            functions = functions.map((fn_name)=> { return fn_string( cb_context[fn_name] ) })
    
            var worker_file = window.URL.createObjectURL( new Blob(["self.addEventListener('message', function(e) { var bb = {}; var args = []; for (fn of e.data.functions) { bb[fn.name] = new Function(fn.args, fn.body); args.push(fn.name)}; var callback = new Function( e.data.callback.args, e.data.callback.body); args = args.map(function(fn_name) { return bb[fn_name] });  var result = callback.apply(null, args) ;self.postMessage( result );}, false)"]) )
            var worker = new Worker(worker_file)
    
            worker.postMessage({ callback: callback, functions: functions })
    
            worker.addEventListener('error', function(error){ return reject(error.message) })
    
            worker.addEventListener('message', function(e) {
                resolve(e.data), worker.terminate()
            }, false)
    
            //From function to string, with its name, arguments and its body
            function fn_string (fn) {
                var name = fn.name, fn = fn.toString()
    
                return { name: name, 
                    args: fn.substring(fn.indexOf("(") + 1, fn.indexOf(")")),
                    body: fn.substring(fn.indexOf("{") + 1, fn.lastIndexOf("}"))
                }
            }
        })
    }
    
    //random blocking function
    function blockCpu(ms) {
        var now = new Date().getTime(), result = 0
        while(true) {
            result += Math.random() * Math.random();
            if (new Date().getTime() > now +ms)
                return;
        }   
    }

提交回复
热议问题