文章目录
promise面试题
Promise是JavaScript中用于处理异步操作的一个对象,使得异步编程更加简洁和易于理解。
状态
- 状态:pending resolved rejected
- pending——>resolved pending——>rejected 变化不可逆
状态表现
- pending状态< pending>,不会触发then和catch
- resolved状态< fulfilled>,会触发后续的then回调函数
- rejected状态< rejected>,会触发后续的catch回调函数
then和catch改变状态
- then正常返回resolved,里面有报错则返回rejected
- catch正常返回resolved,里面有报错则返回rejected
saync/await
- async/await 异步回调callback hell
- Promise then catch 链式调用,也是基于回调函数
- async/await是同步语法,消灭回调函数
saync/await和Promise的关系
- 执行async函数,返回的是promise对象
- await 相当于Promise的then
- try…catch可捕获异常,代替了promise的catch
手写promise
class MyPromise {
state = 'pending' // 状态:'pending' 'fulfilled' 'rejected'
value = undefined // 成功后的值
reason = undefined // 失败后的原因
resolveCallbacks = [] // pending 状态下,存储成功的回调
rejectCallbacks = [] // pending 状态下,存储失败的回调
constructor(fn) {
const resolveHandler = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled'
this.value = value
this.resolveCallbacks.forEach(fn => fn(this.value))
}
}
const rejectHandler = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected'
this.reason = reason
this.resolveCallbacks.forEach(fn => fn(this.reason))
}
}
try {
fn (resolveHandler, rejectHandler)
} catch (err) {
}
}
then(fn1, fn2) {
// 当pending状态下,fn1 fn2会被存储到callbacks中
fn1 = typeof fn1 === 'function' ? fn1 : (v) => v
fn2 = typeof fn2 === 'function' ? fn2 : (e) => e
if(this.state === 'pending') {
const p1 = new MyPromise((resolve, reject) => {
this.resolveCallbacks.push(() => {
try {
const newValue = fn1(this.value)
resolve(newValue)
} catch (err) {
reject(err)
}
})
this.rejectCallbacks.push(() => {
try {
const newReason = fn2(this.reason)
reject(newReason)
} catch (err) {
reject(err)
}
})
})
return p1
}
if(this.state === 'fulfilled') {
const p1 = new MyPromise((resolve, reject) => {
try {
const newValue = fn1(this.value)
resolve(newValue)
} catch (err) {
reject(err)
}
})
return p1
}
if(this.state === 'rejected') {
const p1 = new MyPromise((resolve, reject) => {
try {
const newReason = fn2(this.reason)
reject(newReason)
} catch (err) {
reject(err)
}
})
return p1
}
}
// 就是then的一个语法糖
catch(fn2) {
this.then(unll, fn2)
}
}
Mypromise.all = function (promiseList) {
const p1 = new Promise((resolve, reject) => {
const len = promiseList.length
const currentCount = 0
const resultArray = [] // 存储 promiseList 所有结果
promiseList.forEach(fn => {
fn.then(data => {
resultArray.push(data)
currentCount++ // resolveCount必须在then里面做 ++
if (currentCount === len) {
resolve(resultArray) // 已经遍历到了最后一个promise
}
}).catch((err) => {
reject(err)
})
})
})
return p1
}
Mypromise.race = function (promiseList = []) {
const isReason = false // 标记
const p1 = new Promise((resolve, reject) => {
promiseList.forEach(fn => {
fn.then((data) => {
if (!isReason) {
resolve(data)
isReason = true
}
}).catch((err) => {
reject(err)
})
})
})
return p1
}
使用promise
const p = new Promise((resolve,reject)=>{
//在回调函数中启动异步任务
setTimeout(()=>{
if(成功){
resolve(实参);
}else{
reject(实参);
}
},2000)
})
p.then((value)=>{
//成功
},(reason)=>{
//失败
})
constructor
- constructor() 方法是类的构造函数
- 用于传递参数,返回实例对象,通过 new 命令生成对象实例时 ,自动调用该方法。
- 如果没有显示定义, 类内部会自动给我们创建一个constructor()。
class Person {
constructor(name,age) { // constructor 构造方法或者构造函数
this.name = name;
this.age = age;
} }
// 创建的实例
var ldh = new Person('刘德华', 18);
console.log(ldh.name)
其它地方的手写Promise
function Promise(fn) {
state = 'pending'
value = null
callbacks = []
this.then = function (onFulfilled, onRejected) {
return new Promise(function (resolve, reject) {
handle({
onFulfilled: onFulfilled || null,
onRejected: onRejected || null,
resolve: resolve,
reject: reject
})
})
}
function handle(callback) {
if (state === 'pending') {
callbacks.push(callback)
return
}
var cb =
state === 'fulfilled' ? callback.onFulfilled : callback.onRejected
if (cb === null) {
cb = state === 'fulfilled' ? callback.resolve : callback.reject
cb(value)
return
}
ret = cb(value)
callback.resolve(ret)
}
function resolve(newValue) {
if (newValue && (
typeof newValue === 'object' ||
typeof newValue === 'function')) {
var then = newValue.then
if (typeof then === 'function') {
then.call(newValue, resolve, reject)
return
}
}
state = 'fulfilled'
value = newValue
execute()
}
function reject(reason) {
state = 'rejected'
value = reason
execute()
}
function execute() {
setTimeout(function () {
callbacks.forEach(function (callback) {
handle(callback)
})
}, 0)
}
fn(resolve, reject)
}