1.Promise是什么?
ES6 异步编程的一种解决方案,比传统的方案(回调函数和事件)更加的合理和强大
好处 异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数
promise可以解决异步的问题,本身不能说promise是异步的
2.Promise有几种状态?
它存在三种不同的状态,并在某一时刻只能有一种状态
而且状态只可能从 pending => fulfilled pending => rejected
这两种变化,并且一旦状态改变,任何操作都不能改变这个结果,任何时候得到的都是这个结果
pending: 表示还在执行
resolved: 执行成功
rejected: 执行失败
3.手写Promise
class myPromise {
constructor(executor) {
this.state = "pending";
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
let resolve = (value) => {
if (this.state === "pending") {
this.state = "fulfilled";
this.value = value;
this.onResolvedCallbacks.forEach(fn => fn(this.value));
}
};
let rejected = (reason) => {
if (this.state === "pending") {
this.state = "rejected";
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn(this.reason));
}
};
try {
executor(resolve, rejected);
} catch (e) {
rejected(e);
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value => value);
onRejected = typeof onRejected === 'function' ? onRejected : error => {
throw error
};
let promise2 = new myPromise((resolve, reject) => {
if (this.state === "fulfilled") {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
if (this.state === "rejected") {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
if (this.state === "pending") {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
});
return promise2;
}
catch(callback) {
return this.then(null, callback);
}
}
function resolvePromise(promise, x, resolve, reject) {
if (promise === x) {
return reject(new TypeError("循环引用!"));
}
if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
try {
let then = x.then;
if (typeof then === 'function') {
then.call(x, y => {
resolvePromise(promise, y, resolve, reject);
}, err => {
reject(err);
})
} else {
resolve(x);
}
} catch (e) {
reject(e);
}
} else {
resolve(x);
}
}
4.Promise.all方法
all方法的作用:(获取所有的promise,都执行then,把结果放到数组,一起返回)
输出顺序于传入参数的顺序一样
注意:返回的不是结果数组,还是一个Promise对象
myPromise.all = function (promises) {
return new myPromise((resolve, reject) => {
let result = [];
let counter = 0;
function processData(key, value) {
result[key] = value;
if (++counter === promises.length) {
resolve(result);
}
}
function isPromise(obj) {
return obj !== null && typeof obj.then === "function" &&
(typeof obj === "function"||typeof obj === "object");
}
for (let i = 0; i < promises.length; i++) {
let current = promises[i];
if (isPromise(current)) {
current.then(data => {
processData(i, data);
}, reject);
} else {
processData(i, current);
}
}
});
};
5.Promise.race方法
同样返回的也是一个Promise对象
他类似与all方法,只不过all方法返回全部的结果,race只返回最快的那个
myPromise.race = function (promises) {
return new myPromise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(resolve, reject)
}
})
};