美文网首页
串并行在js中的各种场景

串并行在js中的各种场景

作者: swen_wx | 来源:发表于2017-07-25 00:33 被阅读0次

    首先,让我们先了解下串并行的定义

    串并行指的是任务的执行方式。串行是指多个任务时,各个任务按顺序执行,完成一个之后才能进行下一个。并行指的是多个任务可以同时执行。异步是多个任务并行的前提条件。

    并行

    首先,我们都知道js在浏览器中是单线程(应该说是主线程,还有诸如异步的event线程,绘制线程,当主线程工作时,其他线程会堵塞),也就是说,只有当事件是异步时,浏览器才有可能实现并行逻辑。

    那最常见的并行逻辑自然就是多个异步ajax请求时:


    当es6出来后,解决回调地狱的promise,本质上promise是一个裹着串行执行(顺序执行)外衣的一个并行逻辑(当然,并不是说promise不能用来做串行逻辑,而是大部分情况下):

    let first = new Promise( (resolve) => {
        ajax(url, {}, (data)=>{
                        resolve(data.result);
                })
    });
    let second = new Promise( (resolve) => {
        ajax(url, {}, (data)=>{
                        resolve(data.result);
                })
    });
    
    let third = new Promise((resolve)=> {
        ajax(url, {}, (data)=>{
                        resolve(data.result);
                })
    });
    
    Promise.all([first,second,third]).then((result) => {
        console.log(result);
    });
    

    当你打开chrome的控制台,查看network后,仍能发现是并行请求;
    也就是说promise实际上是先将里面函数执行,保留resolve结果,等到then再把结果传递到下个promise;

    依照 promises 规范,一旦一个 promise 被创建,它就被执行了(这是出自一篇文章,详细讲解了promise的设计有兴趣可以了解,http://fex.baidu.com/blog/2015/07/we-have-a-problem-with-promises/

    在js中,并行逻辑一般只会出现在异步ajax请求,在web worker(有兴趣可以去了解)出现后,出现了新的js线程,在主线程外运行。

    串行

    ok,那如何设计一个串行逻辑呢,如果细心,可以从node.js里面找到答案:

    app.use(function(req, res, next) {
      ......
      next(err);
    });
    

    想到了吗:用next挂载中间件的方式,将事件顺序传递;
    那程序上如何设计呢,编写一个LazyMan吧:

    function _LazyMan(name){
        this.tasks = [];
        var self = this;
        var fn = (function(n){
            var name = n;
            return function(){
                console.log("Hi! This is " + name + "!");
                self.next();
            }
        })(name);
        this.tasks.push(fn);
        setTimeout(function(){
            self.next();
        },0)
    }
    
    _LazyMan.prototype.next = function(){
        var fn = this.tasks.shift();
        fn && fn();
    };
    
    _LazyMan.prototype.eat = function(name){
        var self = this;
        var fn = (function(name){
            return function(){
                console.log("Eat " + name + "~");
                self.next();
            }
        })(name);
        this.tasks.push(fn);
        return this;
    };
    _LazyMan.prototype.sleep = function(time){
        var self = this;
        var fn = (function(time){
            return function() {
                setTimeout(function(){
                    console.log("Wake up after " + time + "s!");
                    self.next();
                }, time * 1000);
            }
        })(time);
        this.tasks.push(fn);
        return this;
    };
    _LazyMan.prototype.sleepFirst = function(time){
        var self = this;
        var fn = (function(time){
            return function() {
                setTimeout(function() {
                    console.log("Wake up after " + time + "s!");
                    self.next();
                }, time * 1000);
            }
        })(time);
        this.tasks.unshift(fn);
        return this;
    };
    function LazyMan(name){
        return new _LazyMan(name);
    }
    

    整个过程就是 由函数进来->调用原型链上方法->传入数组->next中转->数组调用
    1.使用next作为中间件传递的中转站;
    2.链式调用;

    作为es6的语法糖来说,promise我们简单知道使用场景和如何使用也就可以了,不过理解串并行思想对理解js的回调,node的event-loop都很有帮助

    相关文章

      网友评论

          本文标题:串并行在js中的各种场景

          本文链接:https://www.haomeiwen.com/subject/ogfikxtx.html