对象: 皆对象
函数: 特定任务的代码块
构造函数 (被new的才是构造函数 不一定大写都是构造函数)
实例对象 (new 出来返回的对象) 简称对象
函数对象 (对象本身是函数 函数本来就是对象 任何皆对象)
call 第一个参数指向对象, 参数以,
相隔 obj.myFun.call(db,‘s‘, ... ,‘string‘ )
apply 第一个参数指向对象, 参数以数组形式 obj.myFun.apply(db,[‘s‘, ..., ‘string‘ ])
bind 返回的是一个回调函数 第一个参数指向对象obj.myFun.bind(db,‘s‘, ... ,‘string‘ )()
参数类型任意
第一个参数为null或undefined 指向window
自己定义的但不是自己调的
函数A作为参数传递给函数B, 函数B执行函数A 那么A就是回调函数
回调函数没有名称 称为匿名回调函数
回调函数获取异步操作的结果
function fn(callBack){
setTimeout(()=>{
var data = "hello"
callBack(data)
},1000)
}
?
fn((data)=>{
console.log(data)//hello
})
立刻执行, 完全执行完了才结束,不会放到回调队列中
Promise的excutor(执行器)数组遍历相关的回调函数forEach
const arr = [1, 2, 3]
arr.forEach(item =>{
console.log(item)
})
console.log("forEach回调之后")
// 1
// 2
// 3
// forEach回调之后
不会立即执行, 会放入回调队列中将来执行
定时器回调/ajax回调/Promise的成功|失败的回调
setTimeout(()=>{
console.log("timeout")
},0)
console.log("setTimeout之后")
// setTimeout之后
// timeout
宏队列
dom事件对象回调
?
ajax回调
?
定时器回调
微队列
promise回调
?
mutation回调
微队列优先级高
先执行完同步 在微任务 在宏任务 宏任务执行前必须是没有微任务的
setTimeout(()=>{
console.log(1)
},0)
new Promise((resovle) => {
console.log(2)
resovle()
}).then(
()=>{
console.log(3)
}
).then(
()=>{
console.log(4)
}
)
console.log(5)
// 2 5 3 4 1
const first = () => (new Promise((resolve, reject) => {
console.log(3)
let p = new Promise((resolve, reject) => {
console.log(7)
setTimeout(()=>{
console.log(5)
resolve(6)//状态只改变一次
},0)
resolve(1)
})
resolve(2)
p.then((org) => {
console.log(org)
})
}))
?
first().then((org) => {
console.log(org)
})
console.log(4)
?
//3 7 4 1 2 5
setTimeout(() => {
console.log(0)
}, 0)
?
new Promise((resolve, reject) => {
console.log(1)
resolve()
})
.then(() => {
console.log(2)
new Promise((resolve, reject) => {
console.log(3)
resolve()
}).then(() => {
console.log(4)
}).then(() => {
console.log(5)
})
}).then(() => {
console.log(6)
})
?
new Promise((resolve, reject) => {
console.log(7)
resolve()
}).then(() => {
console.log(8)
})
?
// 1 7 2 3 8 4 6 5 0
Error: 所有错误的父类型
ReferenceError: 引用的变量不存在
TypeError: 数据类型不正确的错误
RangeError: 数据值不在其所允许的范围内
SyntaxError: 语法错误
捕获错误: try .... catch
抛出错误: throw error
message属性: 错误相关信息
Cannot read property ‘xxx‘ of undefined
stack属性: 函数调用栈记录信息
01.html:15 Uncaught TypeError: Cannot read property ‘xxx‘ of undefined at 01.html:15
异步编程的新的解决方案 (旧的方案是纯回调)
语法上: 一个构造函数
功能上: promise对象用来封装一个异步操作并可以获取其结果
pending 通过resolve方法变为fulfilled
pending通过reject方法变为rejected
改变只有这两种,且pending对象只能改变一次
无论成功失败都有结果数据
成功为value
失败为reason
new Promise(参数为函数)--->执行异步操作--->成功 执行resolve()-->变为fulfilled状态 pending状态 ----失败 执行reject() ---->变为rejected状态成功----->回调onFulfilled
then()
最后都返回新的Promise对象
失败---->回调onRejected
then()/catch()
//1.创建promise对象 const p = new Promise((resolve, reject) => {//执行构造器 这里是同步的 console.log(‘执行构造器‘) //会先执行 //2. 执行异步操作 setTimeout(() => { const time = Date.now() //3.成功调用resolve(value) if (time % 2 == 0) { resolve(‘成功的数据, time=‘ + time) } else { //失败调用reject(reason) reject(‘失败的数据, time=‘ + time) } }, 1000)}) console.log(‘Promise之后‘) p.then( value => {//接收成功的value数据 onFulfilled console.log(‘成功的回调‘, value) }, reason => {//接收得到失败的reason数据 onRejected console.log(‘失败的回调‘, reason) } )</pre>
为什么用
旧的回调地狱: 回调嵌套回调 多个异步操作 上一次的结果是下一次的条件
不便于异常处理和阅读
Promise使用链式回调 async/await
指定回调函数更加灵活
旧的: 必须在启动异步任务之前指定
Promise: 启动异步任务==> 返回Promise对象===>给Promise对象绑定回调函数(甚至可以在异步中指定) 比如获取到数据需要2s,我3s后指定
一个Promise就是一个异步任务 返回的都是新的Promise
处理异常在最后处理 中间的任何一个错误都会在这里处理 异常传透
async/await
async function request() { try { const result = await doSomething() const newResult = await doSomethingElse(result) const finalResult = await doThirdThing(newResult) console.log(‘Got the final result‘ + finalResult) } catch (error) { failureCallback(error) } }
语法糖 Promise.resolve()/Promise.reject()
Promise.all() 接收Promise数组对象 Promise.all([p1,p2,p3]) 支持不是promise的元素
成功返回的是结果数组对象,顺序对应
失败返回失败原因
Primise.race() 接收Promise数组对象 Promise.race([p1,p2,p3]) 支持不是promise的元素
成功或失败看最先执行完成的结果,最先的成功就成功
和顺序无关
.then是同步的 当时 里面的回调函数(返回的结果回调)是异步的
如何改变Promise状态
1. resolve() 当前pendind ---> fullfilled
reject() 当前pendind ---> rejectedd
抛出异常 当前pendind ---> rejected
一个promise指定多个成功/失败回调函数,都会调用吗
当promise改变为对应状态时都会回调var p = new Promise((resolve,reject) => {
setTimeout(() => {
console.log(‘上课了‘)
resolve()
},10)
})
p.then(() => {
console.log(‘班长:起立‘)
})
p.then(() => {
console.log(‘同学们:老师好‘)
})//上课了 //班长:起立 //同学们:老师好 </pre>
改变promise状态和指定回调函数(then)谁先谁后
1. 都有可能, 正常情况下是先指定回调在改变状态, 但也可能相反 2. 如果先改变状态 1. 在执行器中直接调用resolve()/reject() 不进行异步 2. 延长更长时间才调用then 3. 什么时候才能得到数据 1.如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据 2.如果先改变状态, 那当执行回调时, 回调函数就会调用, 得到数据
链式回调的结果受上一次返回的Promise的影响
没有return 返回undefined
没有对应的回调函数 返回catch
相当于返回 reason => {throw reason}/reason => Promise.reject(reason)
promise.then()返回的新的pomise的结果状态有什么决定
简单表达: 由then()指定的回调函数执行的结果决定详细
如果抛出异常, 新的Promise变为rejected,reason为抛出的异常
如果返回的是非promise的任意值,新的promise变为fullfilled,value为返回的值
如果返回的是另一个新的Promise, 此Promise的结果做为新的结果
Promise如何串联多个操作任务
1. promise的then返回一个新的Promise,可以看成then()的链式调用 return new Promise() 新的里面处理异步 同步可以直接返回结果 不需要new Promise 因为Promise主要处理异步
- 通过then的链式调用串连多个同步/异步任务
promise异常传透
1. 当使用promise的then链式调用时, 可以在最后指定失败的回调2.前面任意操作出了异常, 都会传到最后失败的回调中处理
中断promise链
1. 当使用promise的then链式调用时, 在中间中断, 不在调用后面的回调函数2.办法: 在回调函数中返回一个pending状态的promise对象
return new Promise(()=>{})//返回一个pending状态的promise对象
/* 整体结构 */(function (window) {
const PENDING = ‘penging‘
const FILLFULLED = ‘fillfulled‘
const REJECTED = ‘rejected‘/*
构造函数: excutor
执行器函数: excutor
*/function Promise(excutor) {
//存储当前this
const self = thisself.status = PENDING//初始状态 self.data = undefined//数据结果 self.callbacks = []//每个元素的结构 {onFillfulled(){}, onRejected() {}} function resolve(value) { //如果当前状态不是pending, 直接结束 保证状态只能变一次且只能从pending开始 if (self.status !== PENDING) { return } //改变状态 self.status = FILLFULLED //保存value数据 self.data = value //如果有待执行的callback函数, 立即异步执行回调函数 if (self.callbacks.length > 0) { setTimeout(() => {//放入队列中执行 self.callbacks.forEach(callbacksObj => { callbacksObj.onfullfilled(value) }) }) } } function reject(reason) { //如果当前状态不是pending, 直接结束 保证状态只能变一次且只能从pending开始 if (self.status !== PENDING) { return } //改变状态 self.status = REJECTED //保存value数据 self.data = reason //如果有待执行的callback函数, 立即异步执行回调函数 if (self.callbacks.length > 0) { setTimeout(() => {//放入队列中执行 异步执行 self.callbacks.forEach(callbacksObj => { callbacksObj.onRejected(reason) }) }) } } //立即执行 并且捕获异常 改变状态为reject try { excutor(resolve, reject) } catch (error) { reject(error) }
}
/*
Promise原型对象then和catch
*/Promise.prototype.then = function (onfullfilled, onRejected) {
onfullfilled = typeof onfullfilled === ‘function‘ ? onfullfilled : value => value //向后传递
//指定迷人的失败的回调(实现错误/异常串透的关键)
onRejected = typeof onRejected === ‘function‘ ? onRejected : reason => { throw reason }const self = this //返回一个新的Promise return new Promise((resolve, reject) => { //回调函数封装 function handle(callback) { /* 1.抛出异常 失败 2.非promise 成功 3.是promise 看新的promise的结果 */ try { const result = callback(self.data) if (result instanceof Promise) { // result.then( // value => { // resolve(value) // }, // reason =>{ // reject(reason) // } // ) //--->简化 result.then(resolve, reject) } else { resolve(result) } } catch (error) { reject(error) } } //当前状态是pending 保存回调函数 if (self.status === PENDING) { self.callbacks.push({ onfullfilled(value) { handle(onfullfilled) }, onRejected(reason) { handle(onRejected) } }) } else if (self.status === FILLFULLED) {//如果是fillfulled状态 异步执行onFillfulled改变Promise状态 setTimeout(() => { handle(onfullfilled) }) } else {//如果是rejected状态 异步执行onReject改变Promise状态 setTimeout(() => { handle(onRejected) }) } })
}
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}/*
函数对象的resolve和reject方法
*/Promise.resolve = function (value) {
//返回一个成功/失败的Promise
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(resolve, reject)
} else {//如果不是promise 直接成功
resolve(value)
}
})
}Promise.reject = function (reason) {
//返回一个失败的Promise
return new Promise((resolve, reject) => {
reject(reason)
})
}/*
函数对象的all和race方法
*/Promise.all = function (promises) {
const values = new Array(promises.length)//用来保存成功的value let fillfulled = 0 //保存promises的数量 return new Promise((resolve, reject) => { //遍历promise获取 promises.forEach((p, index) => { Promise.resolve(p).then(//包裹一层 包装为Promise value => {//成功存入数组 fillfulled++ values[index] = value //如果都成功 返回成功 if (fillfulled === promises.length) { resolve(values) } }, reason => {//只要有一个失败, 就失败 reject(reason) } ) }) })
}
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
//遍历promise获取
promises.forEach((p) => {
Promise.resolve(p).then(//包裹一层 包装为Promise
value => {//一旦成功就成功
resolve(value)
},
reason => {//一旦失败就失败
reject(reason)
}
)
})
})
}/*
返回一个promise对象, 他在指定的事件后才确定结果
*/
Promise.resolveDelay = function (value, time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (value instanceof Promise) {
value.then(resolve, reject)
} else {//如果不是promise 直接成功
resolve(value)
}
}, time)
})
}Promise.rejectDelay = function (reason, time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(reason)
}, time)
})
}//向外暴露函数
window.Promise = Promise
})(window)
class版本
/*
整体结构
*/
?
(function (window) {
?
const PENDING = ‘penging‘
const FILLFULLED = ‘fillfulled‘
const REJECTED = ‘rejected‘
?
class Promise {
/*
构造函数: excutor
执行器函数: excutor
*/
constructor(excutor) {
//存储当前this
const self = this
?
self.status = PENDING//初始状态
self.data = undefined//数据结果
self.callbacks = []//每个元素的结构 {onFillfulled(){}, onRejected() {}}
?
function resolve(value) {
//如果当前状态不是pending, 直接结束 保证状态只能变一次且只能从pending开始
if (self.status !== PENDING) {
return
}
?
//改变状态
self.status = FILLFULLED
//保存value数据
self.data = value
//如果有待执行的callback函数, 立即异步执行回调函数
if (self.callbacks.length > 0) {
setTimeout(() => {//放入队列中执行
self.callbacks.forEach(callbacksObj => {
callbacksObj.onfullfilled(value)
})
})
}
}
?
function reject(reason) {
//如果当前状态不是pending, 直接结束 保证状态只能变一次且只能从pending开始
if (self.status !== PENDING) {
return
}
?
//改变状态
self.status = REJECTED
//保存value数据
self.data = reason
//如果有待执行的callback函数, 立即异步执行回调函数
if (self.callbacks.length > 0) {
setTimeout(() => {//放入队列中执行 异步执行
self.callbacks.forEach(callbacksObj => {
callbacksObj.onRejected(reason)
})
})
}
}
?
//立即执行 并且捕获异常 改变状态为reject
try {
excutor(resolve, reject)
} catch (error) {
reject(error)
}
}
?
/*
Promise原型对象then和catch
*/
?
then(onfullfilled, onRejected) {
onfullfilled = typeof onfullfilled === ‘function‘ ? onfullfilled : value => value //向后传递
//指定迷人的失败的回调(实现错误/异常串透的关键)
onRejected = typeof onRejected === ‘function‘ ? onRejected : reason => { throw reason }
?
const self = this
?
?
//返回一个新的Promise
return new Promise((resolve, reject) => {
?
//回调函数封装
function handle(callback) {
/*
1.抛出异常 失败
2.非promise 成功
3.是promise 看新的promise的结果
*/
try {
const result = callback(self.data)
if (result instanceof Promise) {
// result.then(
// value => {
// resolve(value)
// },
// reason =>{
// reject(reason)
// }
// )
//--->简化
result.then(resolve, reject)
} else {
resolve(result)
}
} catch (error) {
reject(error)
}
}
?
//当前状态是pending 保存回调函数
if (self.status === PENDING) {
self.callbacks.push({
onfullfilled(value) {
handle(onfullfilled)
},
onRejected(reason) {
handle(onRejected)
}
})
} else if (self.status === FILLFULLED) {//如果是fillfulled状态 异步执行onFillfulled改变Promise状态
setTimeout(() => {
handle(onfullfilled)
})
} else {//如果是rejected状态 异步执行onReject改变Promise状态
setTimeout(() => {
handle(onRejected)
})
}
})
}
?
catch(onRejected) {
return this.then(undefined, onRejected)
}
?
/*
函数对象的resolve和reject方法
*/
?
static resolve = function (value) {
//返回一个成功/失败的Promise
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(resolve, reject)
} else {//如果不是promise 直接成功
resolve(value)
}
})
}
?
static reject = function (reason) {
//返回一个失败的Promise
return new Promise((resolve, reject) => {
reject(reason)
})
}
?
/*
函数对象的all和race方法
*/
?
static all = function (promises) {
?
const values = new Array(promises.length)//用来保存成功的value
?
let fillfulled = 0 //保存promises的数量
?
return new Promise((resolve, reject) => {
//遍历promise获取
promises.forEach((p, index) => {
Promise.resolve(p).then(//包裹一层 包装为Promise
value => {//成功存入数组
fillfulled++
?
values[index] = value
?
//如果都成功 返回成功
if (fillfulled === promises.length) {
resolve(values)
}
},
reason => {//只要有一个失败, 就失败
reject(reason)
}
)
})
})
}
?
static race = function (promises) {
return new Promise((resolve, reject) => {
//遍历promise获取
promises.forEach((p) => {
Promise.resolve(p).then(//包裹一层 包装为Promise
value => {//一旦成功就成功
resolve(value)
},
reason => {//一旦失败就失败
reject(reason)
}
)
})
})
}
?
/*
返回一个promise对象, 他在指定的事件后才确定结果
*/
static resolveDelay = function (value, time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (value instanceof Promise) {
value.then(resolve, reject)
} else {//如果不是promise 直接成功
resolve(value)