JS中的生成器

生成器是一种特殊的函数,用于异步编程,其定义时有*号,执行时返回迭代器。通过next方法执行函数体,yield语句用于暂停执行并返回值。在for...of循环中可方便使用生成器。生成器可以接收参数,next方法也可传递参数,解决回调地狱问题,常用于处理文件、网络和数据库等异步操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简单介绍

生成器就是以一个特殊的函数,用于实现异步编程。

定义特殊:在定义的时候在function 和函数名之间加上一个 * 号。

执行特殊:执行的时候直接调用不会执行该函数里面的内容,而是输出是一个迭代器对象,可以调用next方法,用这个方法才可以调用函数。

function * gen(){
    console.log('这是一个生成器');
}
let iterator = gen()
//直接调用函数
console.log(iterator);

输出

Object [Generator] {}

加上next方法

console.log(iterator.next());

输出

这是一个生成器
{ value: undefined, done: true }

生成器函数可以出现yield语句(算作函数代码的分隔符)

//yield 定义的是调用next方法返回的value值,next遇到yield就会停止
function * gen(){
    console.log('111');
    yield '两只老虎'
    console.log('222');
    yield '跑得快'
    console.log('222');
}
let iterator = gen()
console.log(iterator.next());

 结果

111
{ value: '两只老虎', done: false }

111 是函数执行结果

{ value: '两只老虎', done: false } 是next方法返回的对象。

上面iterator都出现了,所以我们很自然的想到可以用for...of啦,来试试

function * gen(){
    console.log('111');
    yield '两只老虎';
    console.log('222');
    yield '跑得快';
    console.log('333');
}

for(let v of gen()){
    console.log(v);
    console.log("------");
}

 结果

111
两只老虎
------
222
跑得快
------
333

可以发现,每次拿到的数据是把yield那条语句执行完

生成器函数的参数传递

1、生成器可以传入参数

function * gen(arg){
    console.log(arg);
    yield '两只老虎';
    yield '跑得快';

}

let iterator = gen('参数');
iterator.next()

结果

参数

2、next方法在调用时可以传入参数

传入的实参是上一个yield语句返回的结果

function * gen(){
    let one = yield '两只老虎';
    console.log(one);
    yield '跑得快';

}

let iterator = gen();
iterator.next()
iterator.next('next参数')

结果

next参数

生成器函数解决异步编程问题

有哪些异步操作呢?比如说:文件操作,网络操作(Ajax, request),数据库操作。这里直接用延时函数来代替

实现目标:1s后获取用户数据,执行完成后2s后获取订单数据,执行完成后3s后获取商品数据。

 需要注意的是,1、需要在每个定时器内部加上iterator.next()方法,或者选择在执行的时候每次手动调用next方法;2、数据获取完之后用next传参给yield,可以来处理数据。

function getUsers(){
    setTimeout(() => {
        let data = '用户数据';
        iterator.next(data);
    }, 1000);
}
function getOrders(){
    setTimeout(() => {
        let data = '订单数据';
        iterator.next(data);
    }, 2000);
}
function getGoods(){
    setTimeout(() => {
        let data = '商品数据';
        iterator.next(data);
    }, 3000);
}
function * gen(){
    let users = yield getUsers();
    console.log(users);
    let oders = yield getOrders();
    console.log(oders);
    let goods = yield getGoods();
    console.log(goods);
}
let iterator = gen();
iterator.next()

优点:可以解决回调地狱问题。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值