promise
特点
- 对象的状态不受外界影响。有三种状态:padding(进行中)、fulfilled(已成功)、rejected(已失败),只有异步操作的结果可以决定状态
- 一旦状态确定了,不会再改变,任何时候都是这个结果。状态的改变只有两种结果:padding -> fulfilled 和 padding -> rejected,一般使用 resolved 指代 fulfilled
- 无法取消 promise
then 与 catch
- then:具有两个参数
- resolved 状态的回调函数
- rejected 状态的回调函数(可选)
- catch:是 then 的别名,用于指定发生错误时的回调函数
- then 转成 catch:在 then 回调中抛出错误就会被 catch 捕获
解决回调地狱
手写 promise
let promise = new Promise((resolve, reject) => {
if (true) {
resolve('success');
} else {
reject('error');
}
});
function CustomPromise(config) {
this.status = 'pending';
this.res = '';
let resolve = data => {
this.status = 'fulfilled';
this.res = data;
};
let rejetc = data => {
this.status = 'rejected';
this.res = data;
};
config(resolve, rejetc);
}
CustomPromise.prototype.then = function (config) {
let res = '';
if (this.status === 'fulfilled') {
res = config(this.res);
}
return res || this;
};
CustomPromise.prototype.catch = function (config) {
let res = '';
if (this.status === 'rejected') {
res = config(this.res);
}
return res || this;
};
let p1 = new CustomPromise((resolve, reject) => {
resolve(1);
});
p1.then(res => {
console.log(res);
return Promise.resolve(2);
}).then(res => {
console.log(res);
});
function CustomPromise(config) {
this.status = 'pending';
this.res = '';
this.saveResolve = [];
this.saveReject = [];
let resolve = data => {
if (this.status == 'pending') {
this.status = 'fulfilled';
this.res = data;
this.saveResolve.forEach(val => {
val(this.res);
});
}
};
let reject = data => {
if (this.status == 'pending') {
this.status = 'rejected';
this.res = data;
this.saveReject.forEach(val => {
val(this.res);
});
}
};
config(resolve, reject);
}
CustomPromise.prototype.then = function (config) {
let res = '';
if (this.status == 'pending') {
this.saveResolve.push(config);
}
if (this.status == 'fulfilled') {
res = config(this.res);
}
return res || this;
};
CustomPromise.prototype.catch = function (config) {
let res = '';
if (this.status == 'pending') {
this.saveReject.push(config);
}
if (this.status == 'rejected') {
res = config(this.res);
}
return res || this;
};
let p2 = new CustomPromise((resolve, reject) => {
setTimeout(() => {
resolve('p2 resolve');
}, 1000);
});
p2.then(res => {
console.log(res);
}).then(res => {
setTimeout(() => {
console.log(3);
}, 1000);
});
CustomPromise.all = function (arr) {
let result = [];
let count = 0;
let promise = new CustomPromise((resolve, reject) => {
for (let i = 0; i < arr.length; i++) {
arr[i]
.then(res => {
result.push(res);
count++;
if (count === arr.length) {
resolve(result);
}
})
.catch(err => reject(err));
}
});
return promise;
};
CustomPromise.race = function (arr) {
let promise = new CustomPromise((resolve, reject) => {
for (let i = 0; i < arr.length; i++) {
arr[i].then(res => resolve(res)).catch(err => reject(err));
}
});
};