- vscode插件
- live server 起浏览器 通过localhost
- code runner 可以运行部分代码
callback
高阶函数(aop 偏函数 柯里化)
一个函数的参数是一个函数, 函数返回一个函数
切函数,相当于在函数里面切一个口,放入自己的逻辑
// 装饰器 前端埋点 在ajax中包装一层自己的逻辑
// 判断this是谁,就要看.前面是谁
// 在原型上添加新的的方法
Function.prototype.before = function (callback) {
let self = this // 这个this指的是 fn
return function (val) { // 这里可以用箭头函数
callback() // before 的参数
self(val) // fn 的执行
}
}
function fn(val) {
console.log('一定功能'+ val)
}
fn.before(function(){
cosole.log('在函数前面执行')
})
window.newFn('nihao') // this 为function 所以return 出来函数的this为window,将fn的this保存下来
// after 函数 类似debounce throttle
function after(times, callback) {
return function () {
if (--times === 0) { // 当i减到0,函数执行
callback()
}
}
}
after(3, callback)
// 并发调用接口 两个ajax 使用after方法
let fs = require('fs')
function after(times, callback) {
let result = {}
return function (key, data) {
result[key] = data
if (--times === 0) {
callback(result)
}
}
}
let newFn = after(2, funtion(result) {
console.log(result)
})
fs.readFile('../name.txt', 'utf-8', (err, data) => {
if (err) return console.log('err')
newFn('name', data)
})
fs.readFile('../age.txt', 'utf-8', (err, data) => {
if (err) return console.log('err')
newFn('age', data)
})
// 串行 两个人有关系 上一个人的输出是下一个人的输入
// 并行 两个人没有关系
// 发布 订阅[fn, fn] 先订阅再发布
let fs = require('fs')
function EventEmitter () {
this._arr = [] // 发布和订阅两个人是无关的,是靠中间媒介this._arr
}
EventEmitter.prototype.on = function(callback) {
this._arr.push(callback)
}
EventEmitter.prototype.emit = function () {
this._arr.forEach(fn => fn。apply(this, arguments))
}
let e = new EventEmitter()
let school = {}
e.on(function(data, key) {
school[key] = data;
if (Object.keys(school).length === 2) {
console.log(school)
}
})
fs.readFile('../name.txt', 'utf-8', (err, data) => {
if (err) return console.log('err')
e.emit(data, 'name') // 在每个函数读完之后需要发布一次
})
fs.readFile('../age.txt', 'utf-8', (err, data) => {
if (err) return console.log('err')
e.emit(data, 'age') // 在每个函数读完之后需要发布一次
})
promise
promise 规范 promise a+
promise 是一个类 承诺 允诺 (异步解决方案)
padding 等待状态 -> resolved 成功
padding 等待状态 -> rejected 失败
exexcutor 函数 而且会立即执行,参数是resolved reject
每个promise实例有一个then方法
let promise = new Promise ((resolve, reject) => {
resolve('玩具少')
reject('玩具多')
})
promise.then((val) => {
console.log(val, 'success')
}),function(err) {
console.log(err, 'err')
}
- 手写promise
function Promise (exexcutor) {
this.state = 'padding'
this.value = undefined;
this.reason = undefined;
let self = this;
function resolve(value) {
if (self.status === 'padding') {
self.value = value;
self.status = 'fulfilled'
}
function reject (reason) {
if (self.status){
self.reason = reason;
self.status = 'resolved'
}
}
// 执行器会立即执行
try {
exexcutor(resolve, reject)
} catch(e) {
// 如果报错调用 then方法的reject方法
reject(e)
}
Promise.prototype.then = function (onfulfilled, onrejected) {
let self = this;
if (self.status === 'fulfilled') {
onfulfilled(self.value)
}
if (self.status === 'rejected') {
onreject(self.reason)
}
if (self.status === 'padding') {
}
}
// promise 的发布订阅
function Promise (exexcutor) {
this.state = 'padding'
this.value = undefined;
this.reason = undefined;
let self = this;
// 定义两个队列 存放对应的回调
self.onResolveCallbacks = [] // 成功的回调
self.onRejectCallbacks = [] // 失败的回调
function resolve(value) {
if (self.status === 'padding') {
self.value = value;
self.status = 'fulfilled'
self.onResolveCallbacks.forEach(fn => fn()) // 发布
}
function reject (reason) {
if (self.status){
self.reason = reason;
self.status = 'resolved'
}
}
// 执行器会立即执行
try {
exexcutor(resolve, reject)
} catch(e) {
reject(e)
}
Promise.prototype.then = function (onfulfilled, onrejected) {
let self = this;
if (self.status === 'fulfilled') {
onfulfilled(self.value)
}
if (self.status === 'rejected') {
onreject(self.reason)
}
if (self.status === 'padding') { // 如果是异步的时候, 需要把成功和失败 分别存放到数组里,发布订阅,如果稍后调用了resolve 会热按函数依次执行,执行的时候 会将成功或者失败的的值进行传递
this.onResolveCallbacks.push(function (){
onfulfilled(self.value)
}) // 收集成功的回调 发布
this.onRejectCallbacks.push(function(){
onrejected(self.reason)
}) // 收集失败的回调 发布
}
}
- promise 的链式调用
- 如果then方法中返回的是一个promise 那我就采用这个promise的状态 作为成功哄着失败,把promise的结果作为参数
- 如果返回的是一个普通值 直接作为下一个then的成功的参数
- 在then方法中抛出异常 也会走失败,如果错误中 返回一个普通值 也会变成成功态
- 每个then方法都返回一个新的promise
generator
generator生成器 iterator迭代器 (迭代器有一个next方法,每次都用后都会返回value, done 两个属性)
生成器生成迭代器
// 类数组 有数组 有索引 是个对象 能被迭代
// 给一个对象添加迭代器功能 可以使他被迭代
// 迭代器
let obj = {0:1, 1:2, 2:3, length:3, [Symbol.itertor]: function() {
let self = this;
let index = 0
return {
next() {
return {value: self[index], done: index++ === self.length}
}
}
}}
- 生成器返回的是迭代器 迭代器有next方法 调用next可以返回 value 和done
function* read () { // 生成器
yield 1
yield 2
yield 3
}
let it = read()
console.log(it.next()) // 第一次next是不能传递参数
console.log(it.next())
console.log(it.next())
// 改写上面的迭代器函数
let obj = {0:1, 1:2, 2:3, length:3, [Symbol.iterator]: function *() {
// 每次浏览器都会不停的调用next方法 把yield的结果作为值
let index = 0;
while(index !== this.length) {
yield this[index ++]
}
}}
网友评论