前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >优雅异步编程方式

优雅异步编程方式

作者头像
张炳
发布2020-05-11 10:54:25
4310
发布2020-05-11 10:54:25
举报

并发

同一时间处理多件事情的能力,滚动屏幕,动态请求内容,然后进行渲染

代码语言:javascript
复制
var count = 0,ary = [],total = 30;
for(var i = 0;i < total;i++)
{
    (function(index)
    {
        ajax.(url,function(result)
        {
            ary[index] = result;
            count++;
            if(count == total)
            {
                paint();
            }
        })
    })(i)
}

对于并发处理的多个任务,如果任务与任务之间没有联系,那么这些任务是可以并行执行的,如果任务与任务之间有依赖,那么这些任务就需要串行执行了,因此对于并发的任务处理可以总结为两种情况,一种是并行的任务处理,另一种是串行的任务处理。

并发模型

  • 多线程与锁 ——JAVA
  • CSP(顺序进程通信)——Erlang、Golang
  • 事件循环——Javascript

为什么Javascript不选择多线程?

  1. 简单,不涉及共享数据与锁的处理(最大的共享数据就是DOM,试想下如果多个线程共同操作DOM的可怕后果)
  2. 浏览器的环境并没有很强的并行需求

事件循环

代码语言:javascript
复制
while(1)
{
    var event = EventQueue.shift();
    event.handler();
}

为什么要使用异步? Javascript引擎的并发模型是单线程的事件循环模型,如果对于耗时长的操作使用同步,会使单线程的事件循环模型性能大大降低。

如何获取异步的结果? 为了能获取异步操作的结果,程序使用callback的方式,当操作完成后,往事件队列push一个事件,当事件循环处理这个事件时,发起异步操作时传入的callback就会被调用。

Callback的问题

  1. 代码结构不清晰
  2. 函数复用性差

如何优雅的处理异步

  1. Thunk https://github.com/thunks/thunks
  2. Promise https://www.promisejs.org/
  3. RxJS http://reactivex.io/
  4. generator

Thunk

代码语言:javascript
复制
<!DOCTYPE HTML>
<html lang="zh">
<head>
</head>
<body>
<script src="./thunk.js"></script>
<script>
function get(url,callback)
{
    setTimeout(function()
    {
        callback([1,2,3])
    },500)
}


var thunk = thunks();

var t = thunk(1);
thunk(function(callback)
{
    //return 1
    callback(null,1)
})(function(e,v)
{
    console.log(e);
    console.log(v);
    return thunk(function(callback)
    {
        setTimeout(function()
        {
            callback(null,3)
        },1000)
    })
})(function(e,v)
{
console.log(e);
console.log(v)
})
/*
var getThunk = thunk.thunkify(get,'url');
getThunk(function(data)
{
    console.log(data)
})
*/
</script>
</body>
</html>

Promise

代码语言:javascript
复制
<!DOCTYPE HTML>
<html lang="zh">
<head>
</head>
<body>
<script>
function get(url)
{
    return new Promise(function(resolve,reject)
    {
        setTimeout(function()
        {
            resolve([1,2,3])
        },500)
    })
}

function handle(p)
{
    return new Promise(function(resolve,reject)
    {
        p.then(function(data)
        {
            for(var i = 0,len =data.length;i < len;i++)
            {
                data[i]++;
            }
            resolve(data);
        })
    })
}

var p = get('url');
p = handle(p);
p.then(function(data)
{
    console.log(data);
})
</script>
</body>
</html>

RxJS

代码语言:javascript
复制
<!DOCTYPE HTML>
<html lang="zh">
<head>
</head>
<body>
<button id="a" page="1"></button>
<script src="./rx.js"></script>
<script>
//Example 1
/*var comments = [
    {contentid : '1',content : 'afasfsadf',uin : '1'},
    {contentid : '1',content : 'afasfsadf',uin : '2'},
    {contentid : '1',content : 'afasfsadf',uin : '3'},
    {contentid : '1',content : 'afasfsadf',uin : '4'},
    {contentid : '1',content : 'afasfsadf',uin : '4'}
]
function getComment(page,pagesize)
{
    return new Promise(function(res,rej)
    {
        setTimeout(function()
        {
            res(comments)
        },500)
    });
}
function getNick(uin)
{
    return new Promise(function(res,rej)
    {
        res('w');
    })
}
function getLevel(uin)
{
    return new Promise(function(res,rej)
    {
        res(10);
    })
}
var clicks = Rx.Observable.fromEvent(document.getElementById('a'),'click')
.pluck('target','attributes','page','value')
.flatMap(function(data)
{
    return getComment(data,10)
})
.flatMap(function(data)
{
    var ary = [];
    for(var i = 0;i < data.length;i++)
    {
        (function(index)
        {
            ary[index] = new Promise(function(res,rej)
            {
            
                Promise.all([getNick(data[index].uin),getLevel(data[index].uin)]).then(function(nickandlevel)
                {
                    data[index].nick = nickandlevel[0];
                    data[index].level = nickandlevel[1];
                    res(data[index]);
                })
            })
        })(i)    
    }
    return  Promise.all(ary);
})
clicks.subscribe(function(data)
{
    console.log(data)
})*/

//Example 2
/*var ob1 = Rx.Observable.create(function(observer)
{
    observer.onNext(1);
})

var ob2 = Rx.Observable.create(function(observer)
{
    observer.onNext(2);
})

Rx.Observable.merge(ob1,ob2).bufferWithCount(2).subscribe(function(data)
{
    console.log(data);
})*/
</script>
</body>
</html>

generator

代码语言:javascript
复制
<!DOCTYPE HTML>
<html lang="zh">
<head>
</head>
<body>
<script src="./co.js"></script>
<script>
//Example 1
/*
function sleep(t)
{
    return function(callback)
    {
        setTimeout(function()
        {
            callback()
        },t)
    }
}

function get(url)
{
    return function(callback)
    {
        setTimeout(function()
        {
            callback([1,2,3])
        },500)
    }
}

co(function *()
{
    yield sleep(2000);
    var data = yield get('url');
    console.log(data);
})*/

//Example 2
/*
var script = "onmessage = function(e) { postMessage('msg from worker'); }";
function CoWorker(script)
{
    return function(callback)
    {
        var blob = new Blob([script]);

        var blobURL = window.URL.createObjectURL(blob);

        var worker = new Worker(blobURL);
        worker.onmessage = function(e)
        {
            callback(e.data);
        };
        worker.postMessage(''); 
    }    
}

co(function *()
{
    var data = yield CoWorker(script)
    console.log(data)
})*/

</script>
</body>
</html>
代码语言:javascript
复制
//co.js
function co(generator) {

    var gen = generator();
    function next(result) {
        
        var step = gen.next(result);
        if (!step.done) {
            step.value(next);
        } 
    }
    next();
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 并发
  • 并发模型
  • 事件循环
  • 如何优雅的处理异步
    • Thunk
      • Promise
        • RxJS
          • generator
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档