目录
本次的生成器函数以及promise都是关于异步编程的,如果有对JS异步不明白的小伙伴我建议大家去看我的这篇博客>-<
一.生成器函数
生成器就是一个特殊的函数,用于异步编程
声明方式:function * 函数名( ){ }
function * add(){
console.log('111');
}
正确的调用方法
let a1 = add();
a1.next();
普通的调用方法在这里是不可以的
函数代码的分隔符 yield
function * add(){
console.log('111');
yield '学生';
console.log('222');
yield '老师';
console.log('333');
yield '学习';
console.log('444');
}
我这里用了三个yield,它们将函数代码分割成四块
现在我们来调用函数
let a1 = add();
a1.next();
a1.next();
a1.next();
a1.next();
因为有yield对代码进行分割,所以我们原本需要调用一次就全部输出的内容我们需要调用四次才能够完全显示
同时因为它是一个迭代器对象,所以我们可以使用for…of对其进行遍历
for(let v of add()){
console.log(v);
}
我们来看一下结果
这里我们调用一下next()方法
function * add(){
// console.log('111');
yield '学生';
// console.log('222');
yield '老师';
// console.log('333');
yield '学习';
// console.log('444');
}
let a1 = add();
console.log(a1.next())
console.log(a1.next())
console.log(a1.next())
console.log(a1.next())
结果是这样的
我们先创建一个生成器函数
function * fen(){
yield 111;
yield 222;
yield 333;
}
let a = fen();
console.log(a.next());
其结果是这样的
我们可以传递参数
function * fen(love){
console.log(love);
}
let a = fen('no1');
console.log(a.next());
next方法可以传入实参
下一个next方法传入的实参将作为上一个yield方法的返回值
function * fen(love){
console.log(love); //输出love
const one = yield 111;
console.log(one);
const two = yield 222;
console.log(two);
const three = yield 333;
console.log(three);
}
let a = fen('no1');
console.log(a.next());
console.log(a.next('no2'));
console.log(a.next('no3'));
console.log(a.next('no4'));
注意: 第一次调用next()时传入的值不会使用,只是为了开始执行生成器函数
function * fen(love){
console.log(love); //输出love
const one = yield 111;
console.log(one);
const two = yield 222;
console.log(two);
const three = yield 333;
console.log(three);
}
let a = fen('no1');
console.log(a.next('nox'));
console.log(a.next('no2'));
console.log(a.next('no3'));
console.log(a.next('no4'));
其结果是一样的
实例
1.代码开始执行1s后控制台输出111, 3s后控制台输出222, 6s后控制台输出333
- 普通方法
setTimeout(() => {
console.log(111);
setTimeout(() => {
console.log(222);
setTimeout(() => {
console.log(333);
},3000);
},2000);
},1000);
虽然也会成功执行,但是一旦要求多了就会产生回调地狱,这是不可取的
- 生成器函数
function one(){ //输出111的函数
setTimeout(() => {
console.log(111)
a.next();
},1000)
}
function two(){ //输出222的函数
setTimeout(() => {
console.log(222)
a.next();
},2000)
}
function three(){ //输出333的函数
setTimeout(() => {
console.log(333)
},3000)
}
function * gen(){ //生成器函数
yield one();
yield two();
yield three();
}
let a = gen();
a.next();
附执行结果的视频链接>-<有需求的小伙伴可以前往B站自行观看
利用生成器函数则不会产生回调地狱
2.模拟获取 用户数据 订单信息 商品数据
- 首先我们创建函数
function getUsers(){
setTimeout(() => {
let data = "用户数据"
},1000)
}
function getOrder(){
setTimeout(() => {
let data = "订单信息"
},1000)
}
function getGoods(){
setTimeout(() => {
let data = "商品数据"
},1000)
}
function * gen(){
yield getUsers();
yield getOrder();
yield getGoods();
}
let a = gen();
a.next();
- 调用next方法将数据传入yield中,输出它的返回值
function getUsers(){
setTimeout(() => {
let data = "用户数据"
// 调用next方法,并将数据传入
a.next(data)
},1000)
}
function getOrder(){
setTimeout(() => {
let data = "订单信息"
a.next(data)
},1000)
}
function getGoods(){
setTimeout(() => {
let data = "商品数据"
a.next(data)
},1000)
}
function * gen(){
let users = yield getUsers();
console.log(users);
let order = yield getOrder();
console.log(order);
let goods = yield getGoods();
console.log(goods);
}
let a = gen();
a.next();
附执行结果的视频链接>-<有需求的小伙伴可以前往B站自行观看
二.Promise
Promise是ES6引入的异步编程的新解决方案
Promise的使用
我们先来实例化一个Promise对象
const p = new Promise(function(resolve, reject){
})
它这里有两个参数,我给它们起名为resolve和reject(默认写法,实际上可以起任何名字)
接下来往里面放一个异步函数settimeout
const p = new Promise(function(resolve, reject){
setTimeout(function(){
// resolve代表成功
let data = '用户数据'
resolve(data);
// reject代表失败
let err = '数据读取失败'
reject(err);
}, 1000)
})
调用一下
p.then(function(value){ //成功执行此函数
console.log(value);
}, function(reason){ //失败执行此函数
console.log(reason);
})
要使用的话我们需要调用promise的then方法,该方法中有两个函数,一个成功时执行,一个失败时执行
可以看到我们的结果是这样的
如果我们把它注掉
const p = new Promise(function(resolve, reject){
setTimeout(function(){
// resolve代表成功
// let data = '用户数据'
// resolve(data);
// reject代表失败
let err = '数据读取失败'
reject(err);
}, 1000)
})
在调用后结果是这样的
Promise在这里只是一个简单介绍,整体的使用方法以及过程原理等等我会发在一个新的专栏>-<里,欢迎大家前去阅读。
选集为20,21,22,23,24