1. yield是什么
-
yield是ES6的新关键字,使生成器函数执行暂停,将其后面的表达式的值以对象的形式返回。可以理解为生成器函数专有的return关键字。
-
yield关键字实际返回的是一个迭代器对象,
{value:返回值,done:是否完成}
-
yield无法单独工作,需要配合generator(生成器)的其他函数,如next。
先来个简单的例子:
function* saleCount(){ var saleList = [1,5,9] for (var i=0;i<saleList.length;i++){ //yield 相当于生成器函数专用的return 关键字 yield saleList[i]; } } var fn = saleCount() var res1 = fn.next() //{value: 1, done: false} var res2 = fn.next() //{value: 5, done: false} var res3 = fn.next() //{value: 7, done: false} var res4 = fn.next() //{value: undefined, done: true}
一些说明:
- yield并不能直接生产值,二十产生一个等待输出的函数
- ie浏览器不兼容
- 某个函数包含了yield,意味着这个函数已经是一个generator生成器函数了
- 如果yield在其他表达式中,需要用()单独括起来
- yield本身没有返回值,胡哦着说返回undefined(由next返回)
- next()可无限调用,但是既定循环完成后返回undefined
2.next()函数的参数
模拟一个没有条件的for循环,先在for循环中打断点,看下程序执行中的参数值。
function* saleCount(){ for(var i = 0;true;i++){ // debugger var reset = yield i; if(reset){ i=-1 } } } var fn = saleCount() var res1 = fn.next() //{value: 0, done: false} var res2 = fn.next() //{value: 1, done: false} var res3 = fn.next(true) //{value: 0, done: false}
前两次调用:
第三次调用:
可以发现:
- 调用next(),会产生许多i的值,但是是不会影响reset的值(一直都是undefined),因为yield直接将值return出去了
- 当第三次调用传入参数true时,reset的值就变成了true,是因为传入true时,yield及它的参数整体(yield i) 变成了true赋值给了reset
1.分析
next()传参是对yield + 表达式的整体赋值,不传参yield类似与 reuturn
2.它的意义在于:
可以在不同阶段从外部直接像内部注入不通知来调整函数的行为。
3. 应用:
generator函数+yield+Promise搭配使用
- 1.先定义一个generator函数搭配Promise的语法
- 2.再使用yield返回出promise
- 3.由于使用fn(2).next().value接收的是一个Promise,所以就可以使用.then了
- 4.react里面看不到.next().value这种,说明被封装过了
function* fn(v){
yield new Promise((resolve,reject)=>{
if(v>=1){
resolve('大于1')
}else{
reject('小于1')
}
})
}
console.log(fn(2).next().value)打印出:[object Promise],所以可以使用then()函数了
let fn2 = fn(2).next().value;
fn2.then(v=>{
console.log(v)//打印出 大于1或者小于1
})
react框架的dva js里面的写法:
//业务组件 Tag.jsx
dispath({
type:'user/add',
payload:{},//需要传递的信息
})
.then(result=>{
console.log(result)
})
//model层 user.jsx
*add({payload},{call,put}){
const response yield call(addTag,payload) //call请求里面的yeild看不到.next().value说明被封装了
const {code,msg} = response;
if(code===200){
//do something
return true;//通过return 给dispatch返回回调结果
}else{
//do something
return false
}
}