今天课程中涉及到的已学习知识点
call
方法-文档链接// 以指定的this调用函数,并通过 从第二个参数开始依次传递参数
function func(food,drink){
console.log(this)
console.log(food)
console.log(drink)
}
const obj = {
name:'小黑'
}
func.call(obj,'西蓝花','咖啡')
apply
方法-文档链接// 以指定的this调用函数,并通过 数组的形式 传递参数
function func(food,drink){
console.log(this)
console.log(food)
console.log(drink)
}
const obj = {
name:'小黑'
}
func.apply(obj,['西蓝花','咖啡'])
bind
方法-文档链接function func(food, drink) {
console.log(this)
console.log(food)
console.log(drink)
}
const obj = {
name: '小黑'
}
const bindFunc = func.bind(obj, '花菜')
bindFunc('可乐')
function func(...args){
console.log(args)// 以数组的形式获取传入的所有参数
}
func('西蓝花','西葫芦','西洋参','西芹')
const p = new Promise((resolve, reject) => {
setTimeout(() => {
const num = parseInt(Math.random() * 10)
if (num > 5) {
resolve(`成功啦--${num}`)
} else {
reject(`失败啦--${num}`)
}
}, 1000)
})
p.then(res => {
console.log(res)
}, err => {
console.log(err)
})
// 实例化时支持传入JS对象
const params = new URLSearchParams({ name: 'jack', age: 18 })
// toString方法 返回搜索参数组成的字符串,可直接使用在 URL 上。
console.log(params.toString())
const person = {
name: 'itheima',
foods: ['西蓝花', '西红柿', '西葫芦']
}
// 将传入的对象作为原型,创建一个新对象(浅拷贝)
const clone = Object.create(person)
clone.name = 'itheima'
clone.foods.push('西北风')
console.log(clone.foods === person.foods)// true
const person = {
name: 'itheima',
foods: ['西蓝花', '西红柿', '西葫芦']
}
const son = {
name: 'rose',
}
// 参数1 目标对象
// 参数2 源对象
// 将源对象的自身属性复制到目标对象,并返回目标对象
const returnTarget = Object.assign(son, person)
console.log(returnTarget === son)// true
console.log(son.name)// itheima
console.log(son.foods === person.foods)// true
这一节咱们来学习JS中this相关的知识点
传送门:MDN-this
传送门:MDN-call
传送门:MDN-apply
传送门:MDN-bind
传送门:MDN-箭头函数
传送门:MDN-剩余参数
传送门:MDN-Symbol
这一节咱们会学习的有:
this
指向this
指向call
,apply
,bind
在非严格模式下,总是指向一个对象,在严格模式下可以是任意值,开启严格模式可以使用如下两种方式:
// 为整个脚本开启严格模式
'use strict'
function func() {
// 为函数开启严格模式
'use strict'
}
然后就可以根据不同的模式来确认this指向啦,
全局执行环境中,指向全局对象(非严格模式、严格模式)
函数内部,取决于函数被调用的方式
直接调用的this值:
对象方法调用的this值:
// 1.全局执行环境
// 非严格模式: 不做任何设置,直接写就是非严格模式
// console.log(this) // window
// 严格模式: 代码顶部加上 'use strict' 即可
// 'use strict' // 为整个脚本开启严格模式
// console.log(this) // window
// 2.函数内部
// 2.1 直接调用-非严格模式
// function func() {
// console.log(this) // 全局对象window
// }
// func()
// 2.1 直接调用-严格模式
// function func() {
// 'use strict'
// console.log(this) // undefined
// }
// func()
// 2.2 对象方法调用
// const food = {
// name: '猪脚饭',
// eat() {
// console.log('吧唧吧唧')
// console.log(this)
// }
// }
// food.eat()
如何确认this指向:
全局执行环境中,指向全局对象(非严格模式、严格模式)
如何开启严格模式:
// 为整个脚本开启严格模式
'use strict'
function func() {
// 为函数开启严格模式
'use strict'
}
函数内部,取决于函数被调用的方式
直接调用的this值:
对象方法调用时的this值为调用者
主要有2类改变函数内部this
指向的方法:
调用函数并传入具体的this
:
call
:
this
apply
-数组作为参数
this
创建绑定this
的函数:
this
的新函数调用函数并传入具体的this:
function funcA(p1, p2) {
console.log('funcA-调用')
console.log(this)
console.log('p1:', p1)
console.log('p2:', p2)
}
const obj = {
name: 'jack'
}
// call参数
// 参数1 this值
// 参数2-参数n 挨个传入函数的参数
funcA.call(obj, 1, 2)
// apply参数
// 参数1 this值
// 参数2 以数组的形式传入函数的参数
funcA.apply(obj, [3, 4])
创建绑定this的函数:
function funcB(p1, p2) {
console.log('funcB-调用')
console.log(this)
console.log('p1:', p1)
console.log('p2:', p2)
}
const person = {
name: 'itheima'
}
// bind参数
// 参数1 this值
// 参数2-参数n 绑定的参数
const bindFuncB = funcB.bind(person, 123)
bindFuncB(666)
const student = {
name: 'lilei',
sayHi: function () {
console.log(this)
// 箭头会从自己作用域链的上一层继承this
const inner = () => {
console.log('inner-调用了')
console.log(this)
}
inner()
}
}
student.sayHi()
如何改变this
指向,有2类改变this
指向的方法,分别是:
调用函数时并传入具体的this
call
:从第二个参数开始挨个传递参数
apply
:在第二个参数以数组的形式传递参数
创建函数时绑定this
?
bind
:返回一个绑定了this
以及参数(可选)的新函数
箭头函数:创建时会绑定上一级作用域中的this
这一节咱们来实现myCall
方法,实际用法和call
方法一致,核心步骤有4步
const person = {
name: 'itheima'
}
function func(numA, numB) {
console.log(this)
console.log(numA, numB)
return numA + numB
}
// 参数1:指定的this值
// 参数2-参数n:原函数参数
const res = func.myCall(person, 2, 8)
console.log('返回值为:', res)
myCall
?this
为某个对象?myCall
接收参数2-参数n?myCall
?// 1. 如何定义`myCall`
Function.prototype.myCall = function () {
// 逻辑略
}
// 2 设置this并调用原函数
Function.prototype.myCall = function (thisArg) {
// this 是调用myCall的 函数
// thisArg 指定的this
// 为他添加一个自定义属性,让函数成为他的该属性
thisArg['fn'] = this
// 调用并获取结果
const res = thisArg['fn']()
// 移除添加的自定义属性
delete thisArg['fn']
}
// 3 接收剩余参数并返回结果
Function.prototype.myCall = function (thisArg, ...args) {
thisArg['fn'] = this
// 调用并获取结果
const res = thisArg['fn'](...args)
// 移除添加的自定义属性
delete thisArg['fn']
// 返回调用结果
return res
}
// 4 使用`Symbol`调优`myCall`
Function.prototype.myCall = function (thisArg, ...args) {
// 使用Symbol生成唯一标记,避免和原属性冲突
const fn = Symbol()
thisArg[fn] = this
const res = thisArg[fn](...args)
// 移除添加的自定义属性
delete thisArg[fn]
// 返回调用结果
return res
}
// --------测试代码--------
const person = {
name: 'itheima'
}
function func(numA, numB) {
console.log(this)
console.log(numA, numB)
return numA + numB
}
// 参数1:指定的this值
// 参数2-参数n:原函数参数
const res = func.myCall(person, 2, 8)
console.log('返回值为:', res)
手写call方法的步骤为
function
的原型上添加myCall
方法,保证所有函数都可以调用this
指向delete
关键字删除上一步动态增加的方法Function.prototype.myCall = function (thisArg, ...args) {
const fn = Symbol()
thisArg[fn] = this
const res = thisArg[fn](...args)
delete thisArg[fn]
return res
}
这一节咱们来实现myApply
方法,实际用法和apply
方法一致,核心步骤依旧4
步
const person = {
name: 'itheima’
}
function func(numA, numB) {
console.log(this)
console.log(numA, numB)
return numA + numB
}
const res = func.myApply(person, [2, 8])
console.log('返回值为:', res)
如何定义myApply
?
如何让函数内部的this
为某个对象?
对象.方法()
调用即可Symbol
来生成方法名如何让myApply
接收参数?
...
展开// 1. 如何定义`myApply`
Function.prototype.myApply = function () {
// 逻辑略
}
// 2 如何让函数内部的`this`为某个对象
Function.prototype.myApply = function (thisArg) {
// 为他添加一个自定义属性,让函数成为他的该属性
// 使用Symbol生成唯一标记,避免和原属性冲突
const fn = Symbol()
thisArg[fn] = this
const res = thisArg[fn](...args)
// 移除添加的自定义属性
delete thisArg[fn]
// 返回调用结果
return res
}
// 3 如何让`myApply`接收参数
Function.prototype.myApply = function (thisArg, args) {
const fn = Symbol()
thisArg[fn] = this
// 调用并获取结果
// 用... 将args展开传入
const res = thisArg[fn](...args)
delete thisArg['fn']
// 返回调用结果
return res
}
// 测试代码
const person = {
name: 'itheima’
}
function func(numA, numB) {
console.log(this)
console.log(numA, numB)
return numA + numB
}
const res = func.myApply(person, [2, 8])
console.log('返回值为:', res)
手写apply方法
function
的原型上添加myApply
方法,保证所有函数都可以调用this
指向delete
关键字删除上一步动态增加的方法...
运算符展开数组Function.prototype.myApply = function (thisArg, args) {
const fn = Symbol()
thisArg[fn] = this
const res = thisArg[fn](...args)
delete thisArg[fn]
return res
}
这一节咱们来实现myBind
方法,实际用法和bind
方法一致,核心步骤为2步
const person = {
name: 'itheima'
}
function func(numA, numB, numC, numD) {
console.log(this)
console.log(numA, numB, numC, numD)
return numA + numB + numC + numD
}
const bindFunc = func.myBind(person, 1, 2)
const res = bindFunc(3, 4)
console.log('返回值:', res)
this
的函数?// 1 如何返回一个绑定了`this`的函数
Function.prototype.myBind = function (thisArg) {
// myBind函数调用时,this就是函数本身
return () => {
// 通过call方法将传入的 thisArg 作为this进行调用
this.call(thisArg)
}
}
// 2 如何实现绑定的参数,及传入的参数合并
// ...args 接收绑定参数
Function.prototype.myBind = function (thisArg, ...args) {
// ...args2 接收调用时的参数
return (...args2) => {
// thisArg 需要指定的this
// args 调用myBind时传入的参数
// args2 调用新函数时传入的参数
return this.call(thisArg, ...args, ...args2)
}
}
// 测试代码
const person = {
name: 'itheima'
}
function func(numA, numB, numC, numD) {
console.log(this)
console.log(numA, numB, numC, numD)
return numA + numB + numC + numD
}
const bindFunc = func.myBind(person, 1, 2)
const res = bindFunc(3, 4)
console.log('返回值:', res)
手写bind方法
function
原型上添加myBind
函数,参数1为绑定的this,参数2-参数2为绑定的参数call
进行this和参数绑定call
的参数2和参数3指定绑定的参数,和调用时传递的参数Function.prototype.myBind = function (thisArg, ...args) {
return (...args2) => {
return this.call(thisArg, ...args, ...args2)
}
}
这一节咱们来学习如何在JS中实现继承,首先看看在ES6之前可以如何实现继承
传送门:继承与原型链
传送门:继承(计算机科学)
传送门:JavaScript高级程序设计
传送门:MDN-Object.create
传送门:MDN-Object.assign
**继承:**继承可以使子类具有父类的各种属性和方法,而不需要再次编写相同的代码
这一节咱们会学习ES5中常见的继承写法(命名来源于 《JavaScript高级程序设计》)
// 父类
function Parent(){
this.name = name
this.foods = ['西蓝花', '西红柿']
this.sayFoods = function () {
console.log(this.foods)
}
}
**核心步骤:**希望继承谁,就将谁作为原型
**缺点:**父类中的引用数据类型,会被所有子类共享
// 父类
function Parent(name) {
this.name = name
this.foods = ['西蓝花', '西红柿']
this.sayFoods = function () {
console.log(this.foods)
}
}
// 子类
function Son() {
}
// 将父类的实例 作为子类的原型
Son.prototype = new Parent('jack')
const s1 = new Son()
s1.sayFoods()// ['西蓝花', '西红柿']
const s2 = new Son()
s2.sayFoods() // ['西蓝花', '西红柿']
s2.foods.push('西葫芦')
s2.sayFoods()// ['西蓝花', '西红柿', '西葫芦']
s1.sayFoods()// ['西蓝花', '西红柿', '西葫芦']
ES5-原型链实现继承
**核心步骤:**在子类的构造函数中通过call
或apply
父类的构造函数
**缺点:**子类没法使用父类原型上的属性/方法
// 父类
function Parent(name) {
this.name = name
}
Parent.prototype.sayHi = function () {
console.log('你好,我叫:', this.name)
}
// 子类
function Son(name) {
Parent.call(this, name)
}
const s1 = new Son('lucy')
const s2 = new Son('rose')
s1.sayHi() // 报错
ES5-构造函数继承
call
或者apply
调用父类的构造函数通过组合继承,结合上面2种方法的优点
核心步骤:
**特点:**调用了2次构造函数
// 父类
function Person(name) {
this.name = name
}
// 方法加父类原型上
Person.prototype.sayHi = function () {
console.log(`你好,我叫${this.name}`)
}
// 子类构造函数
function Student(name, age) {
// 调用父类构造函数传入this
Person.call(this, name)
// 子类独有的属性和方法单独设置
this.age = age
}
// 设置子类的原型为 父类实例
Student.prototype = new Person()
// 调用子类的构造函数
const s = new Student('李雷', 18)
// 可以使用原型链上的 属性和方法 也可以使用 通过构造函数获取的父类的属性和方法
ES5-组合继承
组合继承的核心步骤有2步:
组合继承的特点:调用2次父类的构造函数,浪费性能
直接基于对象实现继承
**核心步骤:**对某个对象进行浅拷贝(工厂函数或Object.create),实现继承
**缺点:**父类中的引用数据类型,会被所有子类共享
// 可以用 Object.create替代
function objectFactory(obj) {
function Fun() { }
Fun.prototype = obj
return new Fun()
}
const parent = {
name: 'parent',
age: 25,
friend: ['rose', 'ice', 'robot'],
sayHi() {
console.log(this.name, this.age)
}
}
const son1 = objectFactory(parent)
const son2 = objectFactory(parent)
son1.friend.push('lucy')
console.log(son2.friend)
ES5-原型式继承
Object.create
实现,不需要调用构造函数即可实现继承,主要针对于继承对象的情况核心步骤:
定义工厂函数,并在内部:
function createAnother(origin) {
// Object.create基于原型创建新对象,对属性进行浅拷贝
const clone = Object.create(origin)
// 为对象增加属性/方法
clone.sayHi = function () {
console.log('你好')
}
return clone
}
const parent = {
name: 'parent',
foods: ['西蓝花', '炒蛋', '花菜']
}
const son1 = createAnother(parent)
const son2 = createAnother(parent)
寄生式继承
寄生式继承的核心步骤是:基于对象创建新对象(可以使用Object.create
),并且为新创建的对象增加新的属性和方法
寄生式继承和上一节学习的原型式继承的区别是:创建出来的新对象,会额外的增加新的属性/方法
所谓寄生组合式继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。其背 后的基本思路是:不必为了指定子类型的原型而调用超类型的构造函数,我们所需要的无非就是超类型 原型的一个副本而已。
核心步骤:
// 继承原型函数
function inheritPrototype(son, parent){
const prototype = object.create(parent.prototype)
prototype.constructor = son
son.prototype = prototype
}
// 父类
function Parent(name) {
this.name = name
this.foods = ['西蓝花', '西葫芦', '西红柿']
}
Parent.prototype.sayHi = function () {
console.log(this.name, `我喜欢吃,${this.foods}`)
}
// 子类借用父类的构造函数
function Son(name, age) {
Parent.call(this, name)
this.age = age
}
// 完成原型继承
inheritPrototype(Son,Parent)
// 可以继续在原型上添加属性/方法
Son.prototype.sayAge = function () {
console.log('我的年龄是', this.age)
}
const son1 = new Son('jack', 18)
const son2 = new Son('rose', 16)
ES5-寄生组合式继承
这一节咱们来学习在ES6中class关键字的使用,并且使用它来实现继承
传送门:mdn类
传送门:阮一峰ES6-class
传送门:mdn-super
ES6中推出了class
类,是用来创建对象的模板.class
可以看作是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class
写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
这一节咱们会学习:
核心语法:
// 定义类
class Person {
// 实例属性,方便一眼确认有哪些
name
food
// 构造方法,类似于构造函数,new的时候会调用,内部的this就是实例化的对象
constructor(name, food) {
this.name = name
this.food = food
}
// 实例方法
sayHi() {
console.log(`你好,我叫${this.name},我喜欢吃${this.food}`)
}
}
const p = new Person('小黑', '西蓝花')
p.sayHi()
class核心语法:
class 类名{}
的形式来定义类方法名(){}
constructor
进行添加new 类名()
创建实例,会调用构造函数constructor
class Person{
name
food='西兰花炒蛋'
constructor(name){
this.name=name
}
sayHi(){
console.log('你好,我叫:',this.name)
}
}
关键语法:
// 在上一份代码的基础上继续编写下面代码
class Student extends Person {
song
constructor(name, food, song) {
// 子类构造函数使用this以前必须调用super
super(name, food)
this.song = song
}
// 添加方法
sing() {
console.log(`我叫${this.name},我喜欢唱${this.song}`)
}
}
const s = new Student('李雷', '花菜', '孤勇者')
s.sayHi()
s.sing()
class实现继承
extends
继承继承父类super
关键字调用父类的构造函数补充语法:
class Person {
constructor(name) {
this.name = name
}
// 通过#作为前缀添加的属性会变为私有
// 私有属性
#secret = '我有一个小秘密,就不告诉你'
// 私有方法
#say() {
// 私有属性可以在
console.log('私有的say方法')
}
info() {
// 在类的内部可以访问私有属性调用私有方法
console.log(this.#secret)
this.#say()
}
// 通过 static定义静态属性/方法
static staticMethod() {
console.log('这是一个静态方法')
console.log(this)
}
static info = '直立行走,双手双脚'
}
const p = new Person('jack')
console.log(p)
// 外部无法访问 点语法访问直接报错,通过[]无法动态获取
console.log(p['#secret'])
p.info()
// 通过类访问静态属性/方法
Person.staticMethod()
console.log(Person.info)
class语法补充
class中私有属性/方法
#
class中静态属性/方法
static
this
是类这一节咱们来学习内置函数
fetch
传送门-fetch
传送门-Response
传送门-Headers
ajax&axios&fetch的关系:
ajax
:ajax
是一种基于原生 JavaScript 的异步请求技术。它使用 XMLHttpRequest
对象来发送请求和接收响应。
axios
:axios
是一个基于 Promise 的 HTTP 客户端,可以在浏览器和 Node.js 中使用。它提供了更高级别的封装,使发送请求和处理响应更加简单和灵活。
fetch
:fetch
是浏览器内置的 API,用于发送网络请求。它提供了一种现代化、基于 Promise 的方式来进行网络通信。用法和axios
类似,但相比于 axios
,它的功能和封装级别更为简单。
全局的fetch
函数用来发起获取资源请求.他返回一个promise
,这个promise
会在请求响应后被resolve
,并传回Response对象
这一节咱们会学习的有:
fetch
核心语法
fetch
结合URLSearchParams
发送get请求:
const obj = {
name:'jack',
age:18
}
name=jack&age=17
fetch
发送post请求,提交FormData
数据
fetch
发送post请求,提交JSON
数据
核心语法:
fetch(资源地址,{...配置项对象})
.then(response=>{
// 接收请求
})
fetch核心语法
fetch
函数的参数:
fetch
获取到响应结果,需要如何解析:fetch(参数1,参数2)
.then(response=>{
// 接收请求
})
需求:
fetch
结合URLSearchParams
调用地区查询接口;(async function () {
const params = new URLSearchParams({
pname: '广东省',
cname: '广州市'
})
const url = `http://hmajax.itheima.net/api/area?${params.toString()}`
// fetch函数返回的是 Promise对象,通过await等待获取response对象
const res = await fetch(url)
// .json方法返回的是Promise对象 继续通过await等待
const data = await res.json()
})()
fetch结合URLSearchParams发送get请求:
fetch
发送get请求时,不需要设置请求方法,因为默认的就是get
URLSearchParams
可以用来创建或者解析查询字符串,这里通过它将对象转为查询字符串需求:
fetch
发送post请求,提交JSON
数据核心步骤:
; (async function () {
// 通过headers设置请求头
const headers = new Headers()
// 通过 content-type指定请求体数据格式
headers.append('content-type', 'application/json')
// 参数1 url
// 参数2 请求配置
const res = await fetch('http://hmajax.itheima.net/api/register', {
method: 'post',// 请求方法
headers, // 请求头
// 请求体
body: JSON.stringify({ username: 'itheima9876', password: '123456' })
})
const json = await res.json()
console.log(json)
})()
post请求-提交JSON
fetch
函数的第二个参数可以设置请求头,请求方法,请求体,根据接口文档设置对应的内容即可JSON.stringify
将对象转为JSON
需求:
fetch
发送post请求,提交FormData
数据(上传+回显)核心步骤:
FormData
添加文件FormData
不需要设置请求头) <input type="file" class="file" accept="image/*">
<script>
document.querySelector('.file').addEventListener('change', async function (e) {
// 生成FormData对象并添加数据
const data = new FormData()
data.append('img', this.files[0])
const res = await fetch('http://hmajax.itheima.net/api/uploadimg', {
method: 'post',
body: data
})
const json = await res.json()
console.log(json)
})
</script>
post请求-提交FormData
fetch
提交FormData
时不需要额外的设置请求头
实例化FormData
之后可以通过append(key,value)
方法来动态添加数据
ajax&axios&fetch的关系
ajax
是一种基于原生JavaScript的异步请求技术,他使用XMLHttpRequest
对象来发送请求和接收响应—学习原理时适用
axios
是一个基于Promise的http客户端,可以在浏览器和Node.js中使用.他提供了更高级别的封装,使发送请求和处理响应更加简单和灵活—项目开发时适用
fetch
是浏览器内置的API,用于发送网络请求.它基于Promise的方式来进行网络通信.和axios
类似.但是功能和封装级别比axios
更为简单—项目简单,不想导入axios时适用
这一节咱们来学习
generator
传送门-Generator
Generator
对象由生成器函数返回并且它符合可迭代协议和迭代器协议.他可以用来控制流程,语法行为和之前学习的函数不一样
核心语法:
generator
对象yield
表达式的使用for of
获取每一个yield
的值// 1. 通过function* 创建生成器函数
function* foo() {
// 遇到yield表达式时会暂停后续的操作
yield 'a'
yield 'b'
yield 'c'
return 'd'
}
// 2. 调用函数获取生成器
const f = foo()
// 3. 通过next方法获取yield 之后的表达式结果,会被包装到一个对象中
// 执行一次next 即可获取一次 yield之后的表达式结果
const res1 = f.next()
console.log(res1)// {value: 'a', done: false}
const res2 = f.next()
console.log(res2)// {value: 'b', done: false}
const res3 = f.next()
console.log(res3)// {value: 'c', done: false}
// 最后一次可以拿到return的结果
const res4 = f.next()
console.log(res4)// {value: 'd', done: true}
// done 为true之后,获取到的value为undefined
const res5 = f.next()
console.log(res5)// {value: undefined, done: true}
// 4. 通过for of 获取每一个yield之后的值,
const f2 = foo()
for (const iterator of f2) {
console.log(iterator)
}
Generator-核心语法
function* xxx(){}
)来生成Generator
对象:Generator
对象的next
方法可以获取yield
表达式之后的结果**需求:**使用Generator
实现一个id生成器id
function* idGenerator() {
// 逻辑略
}
const idMaker = idGenerator()
// 调用next方法,获取id(每次累加1)
const { value: id1 } = idMaker.next()
console.log(id1)
const { value: id2 } = idMaker.next()
console.log(id2)
核心步骤:
yield
返回id
并累加// 1. 通过function* 创建生成器函数
function* generator() {
let id = 0
// 无限循环
while (true) {
// id累加并返回
yield id++
}
}
// 2. 调用函数获取生成器
const idMaker = generator()
// 3. 需要id的时候 通过next获取即可
const { value: id1 } = idMaker.next()
console.log(id1)
const { value: id2 } = idMaker.next()
console.log(id2)
Generator-id生成器
next
方法时执行,利用这一特点,可以实现任意的生成器,需要时调用next
即可获取结果遇到yield
表达式时会暂停后续的操作
**需求:**使用Generator
实现流程控制
function* weatherGenerator() {
// 逻辑略
yield axios()
}
// 获取Generator实例
const weather = weatherGenerator()
// 依次获取 北上广深的天气 (axios)
weather.next()
核心步骤:
yield
后面跟上天气查询逻辑code
:北京 110100 上海 310100 广州 440100 深圳 440300 <button class="getWeather">天气查询button>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.6/axios.js">script>
<script>
/**
* 需求:流程控制,依次查询,北上广深的天气预报
* 参考code: 北京 110100 上海 310100 广州 440100 深圳 440300
* 接口文档: https://apifox.com/apidoc/project-1937884/api-49760220
* */
function* weatherGenerator() {
// 北京
yield axios('http://hmajax.itheima.net/api/weather?city=110100')
// 上海
yield axios('http://hmajax.itheima.net/api/weather?city=310100')
// 广州
yield axios('http://hmajax.itheima.net/api/weather?city=440100')
// 深圳
yield axios('http://hmajax.itheima.net/api/weather?city=440300')
}
const cityWeather = weatherGenerator()
document.querySelector('.getWeather').addEventListener('click', async () => {
const res = await genCity.next()
console.log(res)
})
script>
Generator-流程控制
Generator
控制流程的本质是利用yield
关键字来分隔逻辑比如示例中依次调用了多个接口,通过yield
分隔,通过next
来触发调用