ES6学习:第十七章 Generator 函数

本文深入探讨了JavaScript中的Generator函数,解析其工作原理,包括如何通过yield表达式暂停和恢复执行流程,以及如何使用next方法获取遍历器对象的状态。此外,还介绍了如何利用Generator函数实现斐波那契数列和异步操作,以及如何与for...of循环结合使用。
//第十七章 Generator 函数
//调用 Generator 函数,返回一个遍历器对象,代表 Generator 函数的内部指针。以后,每次调用遍历器对象的
// next方法,就会返回一个有着value和done两个属性的对象。value属性表示当前的内部状态的值,是yield表达
// 式后面那个表达式的值;done属性是一个布尔值,表示是否遍历结束。

//Generator 函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行
// 的函数。yield表达式就是暂停标志。

function* f() {
    console.log('one');
    yield('hello');
     console.log('two');
    yield('world');
    return 'end';
}
let a = f();  //不会立即执行,调用next方法才会执行
console.log(a, a[Symbol.iterator]); //Object [Generator] {}   [Function: [Symbol.iterator]]
console.log(a.next());  // one { value: 'hello', done: false }
console.log(a.next()); //two { value: 'world', done: false }

//可以把 Generator 赋值给对象的Symbol.iterator属性,从而使得该对象具有 Iterator 接口。
const obj = {};
obj[Symbol.iterator] = f;
console.log([...obj]);  //one two [ 'hello', 'world' ]

//Generator 函数执行后,返回一个遍历器对象。该对象本身也具有Symbol.iterator属性,执行后返回自身。
console.log(a[Symbol.iterator]() === a);  //true

//yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个
// yield表达式的返回值
function* foo(x) {
  var y = 2 * (yield (x + 1));
  var z = yield (y * 3);
  return (x + y + z);
}

let q = foo(5);
console.log(q.next());//{ value: 6, done: false }
console.log(q.next());  //{ value: NaN, done: false }
console.log(q.next());//{ value: NaN, done: true }
console.log(q.next());//{ value: undefined, done: true }

let w = foo(5);
console.log(w.next()); //{ value: 6, done: false }
console.log(w.next(8));  //{ value: 48, done: false }
console.log(w.next(7));//{ value: 28, done: true }

//for...of循环可以自动遍历 Generator 函数运行时生成的Iterator对象,且此时不再需要调用next方法。
//实现斐波那契数
function* feibo() {
    let [pre, cur] = [0,1];
    while(true) {
        yield cur;
        [pre, cur] = [cur, pre + cur];
    }
}

for (const i of feibo()) {
    if (i > 1000) {
        break;
    }
    console.log(i);
}

//为原生的对象添加遍历接口,使用for...of...循环
function* loop(obj) {
    const keys = Reflect.ownKeys(obj);
    for (const key of keys) {
        yield[key, obj[key]];
    }
}
let obj2 = {
    name: 'Lily',
    age: 8,
    sex: '女',
};

for (const [key, value] of loop(obj2)) {
    console.log(key, value);  //name Lily  age 8  sex 女
}

//或者把遍历方法添加到对象的[Symbol.iterator]上
function* loop2() {
    const keys = Reflect.ownKeys(this);
    for (const key of keys) {
        yield[key, this[key]];
    }
}
let obj3 = {
    name: 'Lily',
    age: 8,
    sex: '女',
};
obj3[Symbol.iterator] = loop2;
for (const [key, value] of obj3) {
    console.log(key, value);
    //name Lily  age 8  sex 女  Symbol(Symbol.iterator) [GeneratorFunction: loop2]
}

console.log(obj3[Symbol.iterator]().next());//{ value: [ 'name', 'Lily' ], done: false }

//Generator 函数返回的遍历器对象,还有一个return方法,可以返回给定的值,并且终结遍历 Generator 函数。
function* numbers () {
  yield 1;
  try {
    yield 2;
    yield 3;
  } finally {
    yield 4;
    yield 5;
  }
  yield 6;
}
var g = numbers();
g.next() // { value: 1, done: false }
g.next() // { value: 2, done: false }
g.return(7) // { value: 4, done: false }  (先执行finally语句,再执行return)
g.next() // { value: 5, done: false }
g.next() // { value: 7, done: true }


//yield*表达式,用来在一个 Generator 函数里面执行另一个 Generator 函数
function* genFuncWithReturn() {
  yield 'a';
  yield 'b';
  return 'The result';
}
function* logReturned(genObj) {
  let result = yield* genObj;
  console.log(result);
}

console.log([...logReturned(genFuncWithReturn())]);  //The result  [ 'a', 'b' ]


//多个异步操作形成了强耦合,只要有一个操作需要修改,它的上层回调函数和下层回调函数,可能都要跟着修改。
// 这种情况就称为"回调函数地狱"(callback hell)

//Promise 对象就是为了解决这个问题而提出的。它不是新的语法功能,而是一种新的写法,允许将回调函数的嵌套,
// 改成链式调用(依次写在then方法里)

//整个 Generator 函数就是一个封装的异步任务,或者说是异步任务的容器。异步操作需要暂停的地方,都用yield
// 语句注明
function* gen(x) {
  var y = yield x + 2;
  return y;
}

var g = gen(1);
g.next() // { value: 3, done: false }
g.next() // { value: undefined, done: true
内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值