1.前言
Promise是ES6发布的异步编程的一种解决方案。比传统的解决方案--回调函数和事件,更加合理和强大。它由社区提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象。本文详细讲一下怎么手动实现一个Promise。阅读前请确保已经熟练使用Promise,要不会有些费劲。本文较长,如想看懂请耐心,建议边看边自己写一遍。
原生Promise请看文档:Promise。
2.实现
2.1 认识Promise
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
const p = new Promise((resolve, reject) => {
console.log('new Promise')
// 这里执行异步操作,比如调接口。此处用setTimeout代替
setTimeout(() => {
resolve('Hello Promise')
}, 1000)
})
p.then(res => {
console.log('res========', res)
}, err => {
console.log('err============', err)
})
</script>
</head>
<body>
</body>
</html>
输出如下:
我们简单描述一下Pormsie
1. Promise是一个类,构造函数的参数是一个函数,这个函数的两个参数resolve和reject也是函数。
2. new 一个Promise的实例,在传入的函数里执行异步操作。该函数是同步任务会马上执行。成功则执行resolve函数,失败则执行reject函数。
3. Promise的实例有个then方法,then方法有两个参数。第一个是执行成功时的回调函数,函数参数是执行resolve函数时传入的值。第二个是执行失败时的回调函数,函数参数是执行reject函数时传入的值。then方法是异步调用的,在执行resolve或reject之后执行。
4. Promise的实例支持多次调用then方法,即链式调用。
2.2 从零开始实现Promsie
第一步首先需要一个类,为避免冲突起名为MyPromise。MyPromise的构造函数的参数是一个函数,创建MyPromise的实例时需要执行该函数。该函数有两个参数resolve和reject,这两个函数在MyPromise类中实现。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
class MyPromise {
constructor(executor) {
// 执行传入的函数,为入参resolve和reject绑定this
console.log('执行传入的函数')
executor(this._resolve.bind(this), this._reject.bind(this))
}
// 实现resolve函数
_resolve() {}
// 实现reject函数
_reject() {}
}
const p = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('Hello Promise')
}, 1000)
})
</script>
</head>
<body>
</body>
</html>
此时执行结果如下:
第二步实现Promise的状态。Promise对象有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败),只有异步操作的结果可以决定当前是那种状态。Promise对象的状态改变只有两种情况:
1. pending变为fulfilled
2. pending变为reject
当异步操作成功时调用执行resolve函数,把异步操作的结果(Hello Promise)传给resolve,然后在then方法的回调函数中就可以取到此值。此时状态变为fulfilled。</