博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实例讲解async的generator实现
阅读量:5971 次
发布时间:2019-06-19

本文共 2396 字,大约阅读时间需要 7 分钟。

async是es6提出的一种新的异步语法. 一开始es为了解决异步,使用的是promise, 但看到满屏的then之后,就感觉自己傻逼了. 后来提出了generator, 在底层实现了一个异步的模式, 但需要手动执行. 关于如何使用generator,可以参考,. 本文这里,不探讨怎么使用generato. 而是,如果使用generator和promise 构造出async的表达.

简单异步实现

一般异步的写法就是,传回调嘛,比如:

var ajax = function(url,cb){    // send url    // get res    ...    cb(JSON.parse(result))}

这样,应该最容易写成callback hell. 然后我们引入: generator

function *main() {    var result1 = yield ajax( "http://some.url.1" );    var data = JSON.parse( result1 );    var result2 = yield ajax( "http://some.url.2?id=" + data.id );    var resp = JSON.parse( result2 );}var async = main();async.next();function ajax(url){    // send url    async.next(res);}

伪代码的格式如上所述. 这里,需要主意一个点. 如果,你没有在next()中传入res,like async.next(). 那么,里面result1和result2获得的结果就是undefined.

上面就是基本的generator异步. 那如果使用generator来模拟async呢?
这估计得解释一下async出现的原因

async why?

根据上面的解析,我们可以了解到, 使用next 执行语句时, 只能执行yield后面的表达式. 这样造成的结果就是,不能parallel异步呀. 这样限制性还是很大的。所以,为了解决这个问题,使用到es6提出的Promise对象来进行补充.

这里,增加一个限定规则,即,ajax拉取返回的必须是一个promise对象.

function ajax(url){    return new Promise(function(res,rej){        send(url,function(result){            res(result)        })    })}

我们再补充一下,如果使用generator来对promise进行tricky

function runGenerator(g) {    var it = g(), ret;    (function iterate(val){        ret = it.next( val );        if (!ret.done) {            // 检查是否已经then完成            if ("then" in ret.value) {                // 这一句很关键                ret.value.then( iterate );            }            else {                // 同步回调的trick                setTimeout( function(){                    iterate( ret.value );                }, 0 );            }        }    })();}

OK, 这样, 我们就可以在async里面,使用同步的写法,来代表异步的操作了.

runGenerator(function* (){    var result = yield new Promise(function(res,rej){        setTimeout(function(){            res('ok');        },1000)    });})

由于这里要求的是使用promise, 那么,我们使用Promise.all([xx,xx]) 也是合情合理的. 这样就可以完美的解决掉--并行异步发送。

runGenerator(function* (){    yield Promise.all([ajax('http://villainhr.com'),ajax('http://villainhr.com')])})

对比与,使用async的结构:

(async function(){    await Promise.all([ajax('http://villainhr.com'),ajax('http://villainhr.com')]);})();

是不是感觉一毛一样呢? 不过在实际上操作中, async 还必须对new Promise进行兼容处理. 如果其他人直接传入一个expression, 你也必须保证他是可行的.

在babel中,讲的其实也是这样一个逻辑:

// Inasync function foo() {  await bar();}// Outvar _asyncToGenerator = function (fn) {  ...};var foo = _asyncToGenerator(function* () {  yield bar();});

具体参考:

转载地址:http://qnzox.baihongyu.com/

你可能感兴趣的文章
VS2010项目生成时提示错误“在证书存储区中找不到清单签名证书”?
查看>>
iOS-CoreImage简单使用
查看>>
Query the status of network adapter
查看>>
HDU_1072_Nightmare题解
查看>>
oracle之数据同步:Oracle Sql Loader使用说明(大批量快速插入数据库记录)
查看>>
文件压缩
查看>>
Python学习笔记(六)
查看>>
poj1131
查看>>
go语言使用go-sciter创建桌面应用(八) 窗口显示时,自动加载后端数据。
查看>>
cocos2d: 使用TexturePacker , pvr.ccz, CCSpriteBatchNode, CCSpriteFrameCache
查看>>
手机版本高于xcode,xcode的快速升级
查看>>
java多线程基本概述(二十)——中断
查看>>
OLTP系统的Oracle RAC性能调优,索引分区极大提升提交性能
查看>>
IoC(Inversion of Control,控制反转)模式
查看>>
轻量级数据库Sqlite的使用
查看>>
HUST 1600 Lucky Numbers
查看>>
XTU 1243 2016
查看>>
CodeForces 157C Message
查看>>
Docker Day 4 Docker基础之Dockerfile语法
查看>>
生产环境下,oracle不同用户间的数据迁移。第一部分
查看>>