【co】ES6-20/21 iterator与generator

在这里插入图片描述

ES6-20 iterator与generator
ES6-21 async与await、ES6的模块化

try catch不能捕获异步异常

  • try catch是同步代码
try {setTimeout(() => {console.log(a)})
} catch (e) {console.log(e)
}

在这里插入图片描述

iterator

内部迭代器:系统定义好的迭代器接口(如数组Symbol.iterator)
外部迭代器:手动部署(可以给obj定义外部迭代器)

对于遍历器对象来说,done: false和value: undefined属性都是可以省略的

内部迭代器:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 除了next之外还可以增加return(){},在for…of循环中凡是使用break或者throw new Errow()来终止循环的,会走return
let obj = {a: 1,b: 2,c: 3,[Symbol.iterator]() {let nextIndex = 0let map = new Map()for (let [key, value] of Object.entries(this)) {map.set(key, value)}let mapEntries = [...map.entries()],len = mapEntries.lengthreturn {next() {return nextIndex < len ?{ value: mapEntries[nextIndex++], done: false } :{ value: undefined, done: true }}}}
}
for (let i of obj) {console.log(i)
}
// ["a", 1]
// ["b", 2]
// ["c", 3]

默认调用iterator接口

  • ...
  • for...of
  • Array.from()
  • map\set
  • Promise.all() Promise.race()
  • yield

generator

  • 生成器
  • 用于返回迭代器对象
  • yield只能出现在生成器中
  • yield执行的返回值是undefined(并不产生值)
  • 结合yield使用,能结合next拿到
  • yield暂停代码运行,有记忆功能
  • return代码终止
  • 不调用next时,不会运行test内的代码
function * test(){yield 'a'console.log('第二次调用next时才打印')yield 'b'yield 'c'return 'd'}
let iter = test()
// 不调用next时,不会运行test内的代码
console.log(iter.next()) // 暂停
console.log(iter.next())
console.log(iter.next())
console.log(iter.next()) // 终止 done为true了

在这里插入图片描述

  • 打印iter
    在这里插入图片描述

return

  • 终止迭代,done为true,value取决于是否有返回值
  • 内部return
function* test() {yield 1;return;// 再次调用next,return之后value都是undefinedyield 2;
}
let it = test()
console.log(it.next())
console.log(it.next())
console.log(it.next())

在这里插入图片描述

function* test() {yield 1;return 10;// 返回值yield 2;
}
let it = test()
console.log(it.next())
console.log(it.next())

在这里插入图片描述

  • 外部return,实例调用
function* test() {yield 1;yield 2;
}
let it = test()
console.log(it.next())
console.log(it.return(10))
console.log(it.next())

在这里插入图片描述

throw

  • 必须要在第一次调用next之后调用throw,才能被捕获(捕获区间在try里的第一个yield之后)
  • throw的表达式本身要是正确的
function* test() {try {yield 1;yield 2;} catch (e) {console.log('生成器内部异常', e)}
}
let it = test()
console.log(it.next())
console.log(it.throw(1))
console.log(it.next())

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 多次抛出只会捕获一个
function* test() {try {yield 1;yield 2;} catch (e) {console.log('生成器内部异常', e)}
}
let it = test()
console.log(it.next())
console.log(it.throw(1))
console.log(it.throw(2))

在这里插入图片描述

  • throw的同时,也会往下走一步
function* test() {try {yield 1;yield 2;} catch (e) {console.log('生成器内部异常', e)}yield 3;
}
let it = test()
console.log(it.next())
console.log(it.throw(1)) // 产出的是3不是2

在这里插入图片描述

  • 捕获异步代码
const fs = require('fs')
const util = require('util')
const co = require('co')
let readFile = util.promisify(fs.readFile)
function* read() {try {let val1 = yield readFile('firsttxt', 'utf-8')let val2 = yield readFile(val1, 'utf-8')let val3 = yield readFile(val2, 'utf-8')console.log('inner', val3)} catch (e) {console.log('异常捕获', e)}console.log('正常执行')
}
let it = read()
let promise = co(it)
promise.then((val) => {console.log(val)
})

在这里插入图片描述

for…of循环

  • 直接拿到值了,不是done/value了
function* foo() {yield 1;yield 2;yield 3;yield 4;yield 5;return 6;
}for (let v of foo()) {console.log(v); // 返回的是yield产出的值
}
// 1 2 3 4 5

实现斐波那契

function* fibonacci() {let [prev, curr] = [0, 1];for (;;) {yield curr;[prev, curr] = [curr, prev + curr];}
}for (let n of fibonacci()) {if (n > 1000) break;console.log(n);
}

遍历对象

const obj = {a: 1,b: 2,c: 3
}
function* test(obj) {for (let key in obj) {yield [key, obj[key]]}
}
for (let [key, val] of test(obj)) {console.log(key + ':' + val)
}
const obj = {a: 1,b: 2,c: 3,[Symbol.iterator]: test
}
function* test() {for (let key in this) {yield [key, this[key]]}
}
for (let [key, val] of obj) {console.log(key + ':' + val)
}

yield执行返回值

  • 只能通过next的第二次调用拿到值
const fs = require('fs')function promisifyAll(obj) {for (let [key, fn] of Object.entries(obj)) {if (typeof fn === 'function') {obj[key + 'Async'] = promisify(fn)}}
}
promisifyAll(fs)
function promisify(func) {return function (...args) {return new Promise((resolve, reject) => {func(...args, (err, data) => {if (err) {reject(new Error(err))} else {resolve(data)}})})}
}
let readFile = fs.readFileAsync
function* read() {let val1 = yield readFile('first.txt', 'utf-8')let val2 = yield readFile(val1, 'utf-8')let val3 = yield readFile(val2, 'utf-8')console.log('inner', val3)}
let it = read()
let { value } = it.next()
value.then((val1) => {let { value } = it.next(val1)value.then((val2) => {let { value } = it.next(val2)value.then((val3) => {console.log('val3', val3)it.next(val3)})})
})
// val3 66
// inner 66
let it = read()
function Co(it) {return new Promise((resolve, reject) => {let next = (data) => {let { value, done } = it.next(data)if (done) {resolve(value)} else {value.then((val) => {next(val)})}}next()})
}
let promise = Co(it)
promise.then((val) => {console.log(val)
})
  • 直接使用co包
// npm i co
let co = require('co')
let promise = co(it)
promise.then((val) => {console.log(val)
})

yield*

  • ES6 提供了yield*表达式,用来在一个 Generator 函数里面执行另一个 Generator 函数。
function* bar() {yield 'x';yield* foo();yield 'y';
}// 等同于
function* bar() {yield 'x';yield 'a';yield 'b';yield 'y';
}

async await

  • async替换*
  • await替换yield
  • async函数内无论写return什么,返回值都是promise(隐式通过Promise.resolve()包装了返回值)
const fs = require('fs')
const util = require('util')
const co = require('co')
let readFile = util.promisify(fs.readFile)
async function read() {try {let val1 = await readFile('first.txt', 'utf-8')let val2 = await readFile(val1, 'utf-8')let val3 = await readFile(val2, 'utf-8')console.log('inner', val3)} catch (e) {console.log('异常捕获', e)}console.log('正常执行')}
// let it = read()
// let promise = co(it)
// async await内置执行器 co
let promise = read()
promise.then((val) => {console.log(val)
})
// 也可以在返回的promise.catch里捕获异常

在这里插入图片描述

  • promise内部异常
const fs = require('fs')
const util = require('util')
const co = require('co')
let readFile = util.promisify(fs.readFile)
async function read() {let val1 = await readFile('first.txt', 'utf-8')console.log(a)let val2 = await readFile(val1, 'utf-8')let val3 = await readFile(val2, 'utf-8')console.log('inner', val3)console.log('正常执行')
}
let promise = read()
promise.then((val) => {console.log(val)
}).catch((e) => {console.log('catch到异常', e)
})

在这里插入图片描述

Promise.all

  • 一个出错,在then里都拿不到,会在catch里捕获到第一个错误
const fs = require('fs')
const util = require('util')
let readFile = util.promisify(fs.readFile)
let f = Promise.all([readFile('first.txt', 'utf-8'),readFile('secondtxt', 'utf-8'),readFile('thirdtxt', 'utf-8'),
])
f.then((val) => {console.log('then', val)
}).catch((err) => {console.log('err', err)
})

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/250973.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

驱动芯片

一 LED驱动芯片&#xff1a; 1.1 TM1640:16位数码管驱动芯片&#xff0c;2线制控制&#xff08;CLK/DIN&#xff09;,SCLK低电平时DIN输入&#xff0c;而SCLK高电平时保持DIN保持不变&#xff1b;开始传输&#xff1a;SCLKH时DIN由高变低&#xff0c;停止传输SCLKH时DIN由由低变…

confusion_matrix(混淆矩阵)

作者&#xff1a;十岁的小男孩 凡心所向&#xff0c;素履可往 目录 监督学习—混淆矩阵 是什么&#xff1f;有什么用&#xff1f;怎么用&#xff1f; 非监督学习—匹配矩阵 混淆矩阵 矩阵每一列代表预测值&#xff0c;每一行代表的是实际的类别。这个名字来源于它可以非常容…

Python 21 Django 实用小案例1

实用案例 验证码与验证 KindEditor 组合搜索的实现 单例模式 beautifulsoup4 验证码与验证 需要安装Pillow模块 pip stall pillow1、首先需要借助pillow模块用来画一个验证码图形&#xff0c;这里单独封装了一个py文件&#xff0c;调用一个方法就好了 1 #!/user/bin/env python…

数据恢复软件

链接&#xff1a;https://pan.baidu.com/s/1n6x5vhW-3SY8MAvvnqVtog 密码&#xff1a;thh0转载于:https://www.cnblogs.com/huanu/p/9452039.html

VMware

1.VMware软件安装&#xff1a; https://jingyan.baidu.com/article/9f7e7ec09da5906f281554d6.html 2&#xff0c;镜像文件下载地址&#xff1a;http://www.cnbeta.com/articles/tech/566773.htm 有图形界面。 或是在官网&#xff1a;https://wiki.centos.org/Download 2.cento…

【重要】ES6-23 JavaScript模块化

前端js模块化的演变发展 模块化解决的问题 传统模块化、插件化 CommonJS AMD/CMD ES6模块化 ES6以前 没有js引擎 一开始js写在html的script标签里js内容增多&#xff0c;抽取出index.js文件&#xff0c;外部引入js再增加&#xff0c;index.html对应index.js index2.html对应ind…

jquery --- 多选下拉框的移动(穿梭框)

效果如下: 几个注意地方: 1.多选下拉框需要添加 multiple 2.获取选中的元素KaTeX parse error: Expected EOF, got # at position 3: (#̲id option:selec…(#id option:not(:selected)) 下面是代码的各个部分实现, 方便引用,最后是总体代码,方便理解 添加选中到右边: // …

ES6-24 生成器与迭代器的应用

手写生成器 先done再false&#xff0c;不然index就提前了一步1 var arr [1,2] function generator(arr){var i 0;return{next(){var done i > arr.length ? true : false,value done ? undefined : arr[i];return {value : value,done : done} }} } var gen gener…

jquery --- 收缩兄弟元素

点击高亮的收缩兄弟元素. 思路: 1.点击的其实是tr.(类为parent) 2.toggleClass可以切换样式 3.slblings(’.class’).toggle 可以根据其类来进行隐藏显示 代码如下: <!DOCTYPE html> <html> <head> <meta charset"utf-8"><style>.pa…

Webpack基础

path.resolve // 只要以/开头&#xff0c;就变为绝对路径 // ./和直接写效果相同 var path require("path") //引入node的path模块path.resolve(/foo/bar, ./baz) // returns /foo/bar/baz path.resolve(/foo/bar, baz) // returns /foo/bar/baz path.res…

LeetCode:二叉树相关应用

LeetCode&#xff1a;二叉树相关应用 基础知识 617.归并两个二叉树 题目 Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not. You need to merge them into a new …

jquery --- 网页选项卡

点击,不同的tab_menu,显示不同的tab_box 注意点: 1.获取ul下,当前li的编号. $(‘div ul li’).index(this) 2.显示ul下编号为$index的li -> $(‘ul li’).eq($index) <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <style&g…

Webpack进阶(二)代码分割 Code Splitting

源代码index.js里包含2部分① 业务逻辑代码 1mb② 引入&#xff08;如lodash包&#xff09;的代码 1mb若更新了业务逻辑代码&#xff0c;但在浏览器运行时每次都下载2mb的index.js显然不合理&#xff0c;第三方包是不会变的 手动拆分 webpack.base.js entry: {main: path.re…

5177. 【NOIP2017提高组模拟6.28】TRAVEL (Standard IO)

Description Input Output Solution 有大佬说&#xff1a;可以用LCT做。&#xff08;会吗&#xff1f;不会&#xff09; 对于蒟蒻的我&#xff0c;只好用水法&#xff08;3s&#xff0c;不虚&#xff09;。 首先选出的泡泡怪一定是连续的一段 L&#xff0c; R 然后 L 一定属于虫…

python 3.x 爬虫基础---http headers详解

python 3.x 爬虫基础 python 3.x 爬虫基础---http headers详解 python 3.x 爬虫基础---Urllib详解 python 3.x 爬虫基础---Requersts,BeautifulSoup4&#xff08;bs4&#xff09; python 3.x 爬虫基础---正则表达式 前言  上一篇文章 python 爬虫入门案例----爬取某站上海租房…

Webpack进阶(三)

懒加载 lazy loading 用到的时候才加载vue 首屏不加载index.js const oBtn document.getElementById(j-button) oBtn.onclick async function () {const div await createElement()document.body.appendChild(div) } async function createElement() {const { default: _ …

P2634 [国家集训队]聪聪可可

链接&#xff1a;https://www.luogu.org/problemnew/show/P2634 题目描述 聪聪和可可是兄弟俩&#xff0c;他们俩经常为了一些琐事打起来&#xff0c;例如家中只剩下最后一根冰棍而两人都想吃、两个人都想玩儿电脑&#xff08;可是他们家只有一台电脑&#xff09;……遇到这种问…

算法 --- 快慢指针判断链表是否有环

解题思路: 分别设置2个指针(s,q)指向链表的头部,s每次指向下面一个(s s.next),q每次指向下面2个(q q.next.next). 如果存在环,q总会在某一时刻追上s /*** Definition for singly-linked list.* function ListNode(val) {* this.val val;* this.next null;* }*//**…

node --- 使用nrm改变npm的源

说明: 1.nrm只是单纯的提供了几个常用的下载包的URL地址,方便我们再使用npm装包是 很方便的进行切换. 2.nrm提供的cnpm 和通过 cnpm装包是2个不同的东西(使用cnpm install必须先安装cnpm -> npm install -g cnpm) 安装nrm: // linux $ [sudo] npm install --global nrm// w…

MySQL教程(三)—— MySQL的安装与配置

1 安装MySQL 打开附件中的文件&#xff08;分别对应电脑系统为32/64位&#xff09;。点next。 三个选项&#xff0c;分别对应典型安装、自定义安装和完全安装&#xff0c;在此选择典型安装&#xff08;初学者&#xff09;。 点install。 广告&#xff0c;忽略它。 安装完成…