Comments (1)
Promise 原理
Promise 是异步编程的一种解决方案: 从语法上讲,promise是一个对象,从它可以获取异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。 promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变。创建promise实例后,它会立即执行。
解决问题
promise是用来解决两个问题的:
- 回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象
- promise可以支持多个并发的请求,获取并发请求中的数据
- 这个promise可以解决异步的问题,本身不能说promise是异步的
方法
Promise是一个构造函数,自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法。
手写一个Promise
class MyPromise {
// 构造方法
constructor(executor) {
// 初始化值
this.initValue()
// 初始化this指向
this.initBind()
// Promise中有throw的话,就相当于执行了reject。这就要使用try catch了
try {
// 执行传进来的函数
executor(this.resolve, this.reject)
} catch (error) {
// 捕捉到错误直接执行reject
this.reject(error)
}
}
initValue() {
// 初始化值
this.PromiseResult = null // 最终的值
this.PromiseState = 'pending' // 状态
this.onFulfilledCallbacks = [] // 保存成功回调
this.onRejectedCallbacks = [] // 保存失败回调
}
initBind() {
// 初始化this
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
}
resolve(value) {
// state是不可变的
if (this.PromiseState != 'pending') { return }
// 如果执行resolve,状态变为fulfilled
this.PromiseState = 'fulfilled'
// 终值为传进来的值
this.PromiseResult = value
// 执行保存的成功回调
while (this.onFulfilledCallbacks.length) {
this.onFulfilledCallbacks.shift()(this.PromiseResult)
}
}
reject(reason) {
// state是不可变的
if (this.PromiseState != 'pending') { return }
// 如果执行reject,状态变为rejected
this.PromiseState = 'rejected'
// 终值为传进来的reason
this.PromiseResult = reason
// 执行保存的失败回调
while (this.onRejectedCallbacks.length) {
this.onRejectedCallbacks.shift()(this.PromiseResult)
}
}
then(onFulfilled, onRejected) {
// 接收两个回调 onFulfilled, onRejected
// 参数校验,确保一定是函数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
// 封装一个thenPromise
var thenPromise = new MyPromise((resolve, reject) => {
const resolvePromise = cb => {
setTimeout(() => {
try {
const x = cb(this.PromiseResult)
if (x === thenPromise) {
// 不能返回自身
throw new Error('不能返回自身')
}
if (x instanceof MyPromise) {
// 如果返回值是Promise
// 如果返回值是promise对象,返回值为成功,新promise就是成功
// 如果返回值是promise对象,返回值为失败,新promise就是失败
// 谁知道返回的promise是失败成功?只有then知道
x.then(resolve, reject)
} else {
// 非Promise就直接成功
resolve(x)
}
} catch (error) {
// 处理报错
reject(error)
throw new Error(error)
}
}, 0)
}
if (this.PromiseState === 'fulfilled') {
// 如果当前是成功状态,执行第一个回调
resolvePromise(onFulfilled)
} else if (this.PromiseState === 'rejected') {
// 如果当前是失败状态,执行第二个回调
resolvePromise(onRejected)
} else if (this.PromiseState === 'pending') {
// 如果状态为待定状态,暂时保存两个回调
this.onFulfilledCallbacks.push(resolvePromise.bind(this, onFulfilled))
this.onRejectedCallbacks.push(resolvePromise.bind(this, onRejected))
}
})
// 返回这个包装的Promise
return thenPromise
}
/**
* all
* 接收一个Promise数组,数组中如有非Promise项,则此项当做成功
* 如果所有Promise都成功,则返回成功结果数组
* 如果有一个Promise失败,则返回这个失败结果
* @param {Array} promise
* @returns
*/
static all(promise) {
const result = []
let count = 0
return new MyPromise((resolve, reject) => {
const addData = (index, value) => {
result[index] = value
count++
if (count === result.length) {
resolve(result)
}
}
promise.forEach((promise, index) => {
if (promise instanceof MyPromise) {
promise.then(res => {
addData(index, res)
}, err => reject(err))
} else {
addData(index, promise)
}
})
})
}
/**
* race
* 接收一个Promise数组,数组中如有非Promise项,则此项当做成功
* 哪个Promise最快得到结果,就返回那个结果,无论成功失败
* @param {Array} promise
* @returns
*/
static race(promise) {
return new MyPromise((resolve, reject) => {
promise.forEach((promise, index) => {
if (promise instanceof MyPromise) {
promise.then(res => {
resolve(res)
}, err => {
reject(err)
})
} else {
resolve(promise)
}
})
})
}
/**
* allSettled
* 接收一个Promise数组,数组中如有非Promise项,则此项当做成功
* 把每一个Promise的结果,集合成数组,返回
* @param {Array} promise
* @returns
*/
static allSettled(promise) {
const result = []
let count = 0
return new MyPromise((resolve, reject) => {
const addData = (status, value, i) => {
result[i] = {
status,
value
}
count++
if (count === result.length) {
resolve(result)
}
}
promise.forEach((promise, index) => {
if (promise instanceof MyPromise) {
promise.then(res => {
addData('fulfilled', res, index)
}, err => {
addData('rejected', err, index)
})
} else {
addData('fulfilled', promise, index)
}
})
})
}
/**
* any
* any与all相反
* 接收一个Promise数组,数组中如有非Promise项,则此项当做成功
* 如果有一个Promise成功,则返回这个成功结果
* 如果所有Promise都失败,则报错
* @param {Array} promise
* @returns
*/
static any(promise){
return new MyPromise((resolve,reject)=>{
let count = 0
promise.forEach((promise,index)=>{
promise.then(res=>{
resolve(res)
},err=>{
count++
if(count === promise.length){
reject(new AggregateError('All promises were rejected'))
}
})
})
})
}
}
from trisome.
Related Issues (20)
- 说说什么是工程化? HOT 2
- Webpack loader 与 plugin 的区别 HOT 2
- 说一下Webpack打包原理 HOT 5
- Webpack 有哪些性能优化手段? HOT 2
- 说说Webpack打包流程 HOT 2
- 说说Webpack hash、chuckhash、 contenthash的区别,分别应用于什么场景? HOT 1
- 如何提高Webpack的打包速度? HOT 1
- 如何提高Webpack的构建速度? HOT 1
- 说说 git rebase 和 git merge 的区别 HOT 2
- Babel的原理是什么? HOT 4
- 说一下对http2的理解,它解决了什么问题? HOT 2
- 什么是HTTP队头阻塞?什么是TCP队头阻塞? HOT 2
- HTTP连接为什么要三次握手? HOT 1
- 说说浏览器缓存和HTTP缓存 HOT 2
- 说一下HTTPS的原理 HOT 1
- 说说TCP与UDP的区别 HOT 2
- 什么是无状态协议,HTTP 是无状态协议吗?怎么解决? HOT 2
- 说说web安全及防护措施 HOT 2
- 请求20个接口都对第一屏内容很关键如何做优化? HOT 2
- 如何做web性能优化? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from trisome.