Promise深度解析:状态、链式调用与实现原理
98 浏览量
更新于2024-08-30
收藏 71KB PDF 举报
"Promise的理解与实现"
Promise是JavaScript中用于处理异步操作的重要工具,它的概念源于对未来结果的承诺。Promise有三个基本状态:等待中(pending)、已完成(resolved)和已拒绝(rejected)。一旦Promise从等待状态变为完成或拒绝状态,其状态将永久固定,不可逆。
创建Promise时,会立即执行提供的执行器函数,该函数接收两个参数——resolve和reject。这两个函数用于改变Promise的状态。在以下示例中,虽然尝试在resolve之后调用reject,但实际无效,因为状态一旦改变就不再可变:
```javascript
new Promise((resolve, reject) => {
resolve('success');
reject('reject'); // 无效
});
```
Promise的一个显著特性是支持链式调用。每次调用`.then`都会返回一个新的Promise,这允许我们连续处理多个异步操作。如果在`.then`的回调函数中返回一个值,该值会被包装为`Promise.resolve()`的结果:
```javascript
Promise.resolve(1)
.then(res => { // res为1
console.log(res);
return 2; // 包装成Promise.resolve(2)
})
.then(res => { // res为then()返回的2
console.log(res);
});
```
Promise还帮助解决了回调地狱的问题,通过链式调用简化了异步操作的组织结构。例如:
```javascript
ajax(url)
.then(res => {
console.log(res);
return ajax(url1);
})
.then(res => {
console.log(res);
return ajax(url2);
})
.then(res => console.log(res));
```
尽管Promise有很多优点,但也存在一些缺点。例如,Promise一旦创建就无法取消,这可能导致资源浪费。另外,错误处理需要通过`.catch`或其他回调来捕获,而不是像同步代码那样通过try...catch语句。
要实现一个简单的Promise,我们可以创建一个构造函数,维护状态和结果,以及处理回调函数队列:
```javascript
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
function MyPromise(executor) {
let self = this;
self.status = PENDING;
self.value = undefined;
self.reason = undefined;
self.onResolvedCallbacks = [];
self.onRejectedCallbacks = [];
function resolve(value) {
if (self.status === PENDING) {
self.status = FULFILLED;
self.value = value;
self.onResolvedCallbacks.forEach(callback => callback(value));
}
}
function reject(reason) {
if (self.status === PENDING) {
self.status = REJECTED;
self.reason = reason;
self.onRejectedCallbacks.forEach(callback => callback(reason));
}
}
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
MyPromise.prototype.then = function(onFulfilled, onRejected) {
const promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolve(x);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolve(x);
} catch (e) {
reject(e);
}
}, 0);
} else {
this.onResolvedCallbacks.push(value => {
try {
let x = onFulfilled(value);
resolve(x);
} catch (e) {
reject(e);
}
});
this.onRejectedCallbacks.push(reason => {
try {
let x = onRejected(reason);
resolve(x);
} catch (e) {
reject(e);
}
});
}
});
return promise2;
};
// 示例使用
let p = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('Hello, Promise!');
}, 1000);
});
p.then(result => {
console.log(result);
}, reason => {
console.error(reason);
});
```
这个简易版的Promise实现了基本的功能,包括状态管理、回调处理以及链式调用。然而,它并不完全符合ES6标准的Promise,例如,它没有处理then返回的Promise,也没有catch方法。为了完全兼容,还需要进一步完善和扩展。
195 浏览量
2342 浏览量
270 浏览量
2023-09-04 上传
261 浏览量
2023-07-08 上传
143 浏览量
154 浏览量
121 浏览量
weixin_38499349
- 粉丝: 2
- 资源: 961
最新资源
- XX工程火电施工与验收
- npp-markdown-monokai:Notepad++的Markdown语法高亮
- XX博览园综合开发商业计划书.zip
- starter_architecture_flutter_firebase:Flutter和Firebase实时应用程序的入门架构演示
- Basics-OpenCV
- MapInfoProfessional12 专业网管软件
- 公法、私法与经济法
- city-graph:一个网站,收集不来梅2015年雅各布斯哈克创建的城市的最新图像
- Analise-Turbinas-Artilleros:土耳其联邦调查局调查委员会
- 班39
- naninterp:NaN 上的一维插值。-matlab开发
- 湾沟特大桥施工方案
- lcqmc数据集,包括训练集,验证集和测试集
- 实验3 总线悬挂两个DS18B20之实物实验
- my_data_analysis:数据挖掘案例-第十一章应用系统负载分析与磁盘容量预测的程序实现-时间序列分析
- 结合html5jscss测试程序附