Javascript的异步编程(下)及es6之generator
来源:互联网 发布:unity3d建立一个ui界面 编辑:程序博客网 时间:2024/06/05 00:07
协程有点像函数,又有点像线程。它的运行流程大致如下。
第一步,协程A开始执行。
第二步,协程A执行到一半,进入暂停,执行权转移到协程B。
第三步,(一段时间后)协程B交还执行权。
第四步,协程A恢复执行。
上面流程的协程A,就是异步任务,因为它分成两段(或多段)执行。
读取文件的协程写法如下。
function asnycJob() { // ...其他代码 var f = yield readFile(fileA); // ...其他代码}
上面代码的函数 asyncJob 是一个协程,它的奥妙就在其中的 yield 命令。它表示执行到此处,执行权将交给其他协程。也就是说,yield命令是异步两个阶段的分界线。
协程遇到 yield 命令就暂停,等到执行权返回,再从暂停的地方继续往后执行。它的最大优点,就是代码的写法非常像同步操作,如果去除yield命令,简直一模一样。
//基本用法
{
// generator 特点::有*号,函数体内有yield
let tell =
function
* (){
yield
'a'
;//异步操作需要暂停的地方,都用 yield 语句注明
yield
'b'
;
return
'c'
};
let
k=tell();//这里执行yield前的语句,调用 Generator 函数,会返回一个内部指针(即遍历器 )k
console.log(k.next());//调用指针 g 的 next 方法,会移动内部指针(即执行异步任务的第一段),指向第一个遇到的 yield 语句
console.log(k.next());
console.log(k.next());
console.log(k.next());
//next 方法的作用是分阶段执行 Generator 函数。每次调用 next 方法,会返回一个对象,
//表示当前阶段的信息( value 属性和 done 属性)。value 属性是 yield 语句后面表达式的值,
//表示当前阶段的值;done 属性是一个布尔值,表示 Generator 函数是否执行完毕,即是否还有下一个阶段。
//next 方法返回值的 value 属性,是 Generator 函数向外输出数据;next 方法还可以接受参数,这是向 Generator 函数体内输入数据。
}
Generator 函数内部还可以部署错误处理代码,捕获函数体外抛出的错误。
function* gen(x){ try { var y = yield x + 2; } catch (e){ console.log(e); } return y;}var g = gen(1);g.next();g.throw('出错了');// 出错了
上面代码的最后一行,Generator 函数体外,使用指针对象的 throw 方法抛出的错误,可以被函数体内的 try ... catch 代码块捕获。这意味着,出错的代码与处理错误的代码,实现了时间和空间上的分离,这对于异步编程无疑是很重要的。
//应用--------使用generator创建iterator接口。
{
let
obj={};
obj[Symbol.iterator]=
function
*(){
yield
1;
yield
2;
yield
3;
}
for
(
let
item of obj){
console.log(item)
}
}
下面看看如何使用 Generator 函数,执行一个真实的异步任务。
var fetch = require('node-fetch');function* gen(){ var url = 'https://api.github.com/users/github'; var result = yield fetch(url); console.log(result.bio);}
上面代码中,Generator 函数封装了一个异步操作,该操作先读取一个远程接口,然后从 JSON 格式的数据解析信息。就像前面说过的,这段代码非常像同步操作,除了加上了 yield 命令。
执行这段代码的方法如下。
var g = gen();var result = g.next();result.value.then(function(data){ return data.json();}).then(function(data){ g.next(data);});
上面代码中,首先执行 Generator 函数,获取遍历器对象,然后使用 next 方法(第二行),执行异步任务的第一阶段。由于 Fetch 模块返回的是一个 Promise 对象,因此要用 then 方法调用下一个next 方法。
//使用generator轻松实现抽奖次数限制逻辑实例
//实例
let
draw=
function
(count){
//具体抽奖逻辑
console.log(`剩余${count}次`);
};
let
residue=
function
* (count){
while
(count>0){
count--;
yield
draw(count);
}
};
let
start=residue(5);
let
btn=document.createElement(
"button"
);
btn.id=
"start"
;
btn.textContent=
"抽奖"
;
document.body.appendChild(btn);
console.log(2222222222222);
document.getElementById(
"start"
).addEventListener(
"click"
,
function
(){
start.next();
},
false
);
长轮循
//长轮循
//连续请求服务端接口,当服务端返回为0时,停止查询
let
ajax=
function
* (){
yield
new
Promise(
function
(resolve, reject){
//请求服务端的数据
setTimeout(
function
(){
resolve({code:0})
},200)
})
}
let
pull=
function
(){
let
genertaor=ajax();
let
step=genertaor.next();
step.value.then(
function
(d){
if
(d.code!=0){
setTimeout(
function
(){
console.info(
"wait"
);
pull();
},1000)
}
else
{
console.info(d);
}
})
}
pull();
- Javascript的异步编程(下)及es6之generator
- es6 javascript 的Generator 函数 (下)
- Javascript的异步编程(上)及es6的promise
- 小试ES6:异步编程之Generator
- es6 javascript 的Generator 函数 (上)
- ES6 -- 异步编程神器2:Generator
- ES6 —(Generator 函数的异步应用)
- es6 Generator与异步的同步书写
- es6 之 Generator(一)
- es6 之 Generator(二)
- ES6之生成器(Generator)
- es6 javascript的Class 的 Generator 方法
- ES6 Generator Function 解救异步编程深度嵌套问题
- Javascript异步编程(二: Generator函数)
- JavaScript中的异步编程-ES5 & ES6
- ES6-Generator与异步操作
- 12、ES6 之Generator
- ES6之Generator
- 记录使用tensorflow实现大卷积核卷积的代码
- 十大基于Docker的开发工具
- 匿名类型、扩展方法
- HEIF:Technical information
- mongodb系列-访问控制
- Javascript的异步编程(下)及es6之generator
- 自定义类加载器的问题
- 自定义模型
- wxdl文件详解
- 各种助词用法
- Graebert ARES CommanderEdition 2016 2016.3.1.4045.888 Win64 1CD
- 接口与实验:实验3
- 关于阴阳谜题
- java之final关键字