写一个demo
const demo = new Promise((resolve,reject)=>{
resolve('sajdhgas')
})
demo.then(a =>{console.log(a,'console')})
什么是promise
偷懒用的mdn的图,见谅啊,各位大佬 (- . -)

第一步: then catch 原型链方法 和 this指向
- then:接收两个函数 resolve reject
- catch: 接收一个函数 callback ,callback的参数为 executor,resolve,reject 三个回调的 内部错误捕获处理
- then方法和catch方法 都返回一个新的 promise对象
class PromiseDemo {
constructor(executor){
this.resolveResult = null;
this.rejectResult = null;
const resolve = (a) =>{
this.resolveResult = a;
}
const reject = (a) =>{
this.rejectResult = a;
}
try{
executor(resolve);
}catch(e){
reject(e)
}
}
then = (onResolve,onReject) =>{
if(onReject){
onReject(this.rejectResult)
}else{
onResolve(this.resolveResult)
}
return this
}
catch = onReject =>{
this.then(null,onReject)
}
}
const demo = new PromiseDemo((resolve,reject)=>{
//resolve('sajdhgas')
aaa
})
demo.then(a =>{console.log(a,'then')}).catch(a =>{console.log(a.message,'then')})
第二步: Promise 的状态一旦改变,就永久保持该状态,不会再变了
const PENDING = "pending";
const FULFILLED = "fullilled";
const REJECTED = "rejected";
class PromiseDemo {
constructor(executor) {
this.state = PENDING;
this.resolveResult = null;
this.rejectResult = null;
const resolve = a => {
if (this.state === PENDING) {
this.state = FULFILLED;
this.resolveResult = a;
}
};
const reject = a => {
if (this.state === PENDING) {
this.state = REJECTED;
this.rejectResult = a;
}
};
try {
executor(resolve);
} catch (e) {
reject(e);
}
}
then = (onResolve, onReject) => {
if (onReject) {
onReject(this.rejectResult);
} else {
onResolve(this.resolveResult);
return this;
}
};
catch = onReject => {
this.then(null, onReject);
return this;
};
}
const demo = new PromiseDemo((resolve, reject) => {
resolve("sajdhgas");
resolve("sajdhgas1222");
});
demo
.then(a => {
console.log(a, "then");
})
.catch(a => {
console.log(a, "catch");
});
第三步: 异步回调
给promise内部加一个状态锁 state
对于异步: 在等待过程中,把onResolve存起来,在resolve回调里处理调用
对于同步: 在执行executor的时候把resolve的值存起来,在then里直接调用
const PENDING = "pending";
const FULFILLED = "fullilled";
const REJECTED = "rejected";
class PromiseDemo {
constructor(executor) {
this.state = PENDING;
this.resolveResult = null;
this.rejectResult = null;
this.onReject = null;
this.onResolve = null;
const resolve = a => {
if (this.state === PENDING) {
this.state = FULFILLED;
this.resolveResult = a;
this.onResolve(a);
}
};
const reject = a => {
if (this.state === PENDING) {
this.state = REJECTED;
this.rejectResult = a;
}
};
try {
executor(resolve);
} catch (e) {
reject(e);
}
}
then = (onResolve, onReject) => {
switch(this.state){
case PENDING:
this.onResolve = () => onResolve(this.resolveResult);
return this;
case FULFILLED:
onResolve(this.resolveResult);
return this;
case REJECTED:
this.onResolve = () => onResolve(this.resolveResult);
return this;
default:
break;
}
};
catch = onReject => {
this.then(null, onReject);
return this;
};
}
const demo = new PromiseDemo((resolve, reject) => {
setTimeout(() => {
resolve("sajdhgas");
}, 1000);
});
demo.then(a => {
console.log(a, "then");
});
第四步: 返回一个新的 promise对象 完成链式调用
then方法和catch方法 都返回一个新的 promise对象,Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。
捕获onReslove函数的返回值 并交给resolvePromise 统一处理
const PENDING = "pending";
const FULFILLED = "fullilled";
const REJECTED = "rejected";
class PromiseDemo {
constructor(executor) {
this.state = PENDING;
this.resolveResult = null;
this.rejectResult = null;
this.onReject = null;
this.onResolve = null;
const resolve = a => {
if (this.state === PENDING) {
this.state = FULFILLED;
this.resolveResult = a;
this.onResolve();
}
};
const reject = a => {
if (this.state === PENDING) {
this.state = REJECTED;
this.rejectResult = a;
this.onReject();
}
};
try {
executor(resolve);
} catch (e) {
reject(e);
}
}
then = (onResolve, onReject) => {
const promise2 = new PromiseDemo((resolve, reject) => {
switch (this.state) {
case PENDING:
this.onResolve = () => {
// 这里可以打印到异步 promise的onResolve结果
// 获取onResolve返回值 判断返回值类型
const fulfilledResult = onResolve(this.resolveResult);
resolvePromise(promise2,fulfilledResult, resolve, reject);
};
this.onReject = () => {
const rejectedResult = onReject(this.rejectResult);
resolvePromise(promise2,rejectedResult, resolve, reject);
};
break;
case FULFILLED:
const fulfilledResult = onResolve(this.resolveResult);
resolvePromise(promise2,fulfilledResult, resolve, reject);
break;
default:
const rejectedResult = onReject(this.rejectResult);
resolvePromise(promise2,rejectedResult, resolve, reject);
break;
}
});
return promise2;
};
catch = onReject => {
this.then(null, onReject);
};
}
const resolvePromise = (result, resolve, reject) => {
resolve(result, "a");
};
const demo = new PromiseDemo((resolve, reject) => {
// resolve("sajdhgas1");
setTimeout(() => {
resolve("sajdhgas2");
}, 1000);
});
const a = demo
.then(a => {
console.log(a, "then1");
return "json.post";
})
.then(a => {
console.log(a, "then2");
});
resolvePromise(promise2 , result , resolve,reject)
功能:
- 将这个promise2返回的值传递到下一个then中
- 如果返回一个普通的值,则将普通的值传递给下一个then中 分析
- 如果返回值是一个promise,则获取promise.then 的返回值 再执行一遍resolvePromise 抛出结果给下一个then
- 如果返回值和后面返回的是同一个promise,会陷入死循环
- 如果是其他值则直接返回
- 返回值不可以是null
function resolvePromise(promise2, x, resolve, reject) {
// 只返回onresolve的第一个then 防止多次调用
let called;
if(x === promise2 ){
// reject报错
return reject(new TypeError('Chaining cycle detected for promise'));
}
// 如果是promise
if (x !== null && (typeof x === "function" || typeof x === "object")) {
try {
// 如果onresolve返回值x是一个promise 则x存在then方法
let then = x.then;
if (typeof then === "function") {
if (called) return;
called = true;
// 如果是promise 获取promise.then 的返回值
// 再执行一遍resolvePromise 抛出结果给下一个then
/**
* const a = new PromiseDemo((res,rej)=>{
res(222,'222')
})
a.then.call(this,(a)=>{
console.log(a,'a')
})
*/
then.call(
x, // x是onReslove返回的 promise.then
res => {
// 获取到onReslove 返回的promise.then的结果后调用resolvePromise 返回非promise的值
resolvePromise(promise2, res, resolve, reject);
},
err => {
reject(err);
}
);
} else {
resolve(x);
}
} catch (err) {
if (called) return;
called = true;
reject(err);
}
} else {
resolve(x);
}
}
第五步: 思考验证 —— 链式调用顺序
我尝试用下面的代码验证我写的promise 链式调用顺序 结果代码报错
这里涉及到一个知识点 —— 链式调用顺序
因为在同一个then内的回调callback都是被异步调用的, 所以同一级的then中先调用最外层then再向内层依次执行
- PENDING的时候 resolve和reject必须是异步调用
- resolve和reject如果是value的兼容
- 如果resolve或reject报错,直接返回reject()
- 代码任意地方异常则抛出error
new PromiseDemo((resolve, reject) => {
console.log("log: 外部promise");
resolve();
})
.then(() => {
console.log("log: 外部第一个then");
new PromiseDemo((resolve, reject) => {
console.log("log: 内部promise");
resolve();
})
.then(() => {
console.log("log: 内部第一个then");
})
.then(() => {
console.log("log: 内部第二个then");
});
})
.then(() => {
console.log("log: 外部第二个then");
});
// log: 外部promise
// log: 外部第一个then
// log: 内部promise
// log: 内部第一个then
// log: 外部第二个then
// log: 内部第二个then
下面是完整代码
const PENDING = "pending";
const FULFILLED = "fullilled";
const REJECTED = "rejected";
class PromiseDemo {
constructor(executor) {
this.state = PENDING;
this.resolveResult = undefined;
this.rejectResult = undefined;
this.onResolve = undefined;
this.onReject = undefined;
let resolve = resolveResult => {
if (this.state === PENDING) {
this.state = FULFILLED;
this.resolveResult = resolveResult;
this.onResolve();
}
};
let reject = rejectResult => {
if (this.state === PENDING) {
this.state = REJECTED;
this.rejectResult = rejectResult;
this.onReject();
}
};
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
then = (onResolve, onReject) => {
const promise2 = new PromiseDemo((resolve, reject) => {
switch (this.state) {
case PENDING:
this.onResolve = () => {
setTimeout(() => {
try {
const fulfilledResult = onResolve(this.resolveResult);
resolvePromise(fulfilledResult, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
};
this.onReject = () => {
setTimeout(() => {
try {
const rejectedResult = onReject(this.rejectResult);
resolvePromise(rejectedResult, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
};
break;
case FULFILLED:
setTimeout(() => {
try {
const fulfilledResult = onResolve(this.resolveResult);
resolvePromise(promise2, fulfilledResult, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
break;
default:
setTimeout(() => {
const rejectedResult = onReject(this.rejectResult);
resolvePromise(promise2,rejectedResult, resolve, reject);
}, 0)
break;
}
});
return promise2;
};
catch = onReject => {
this.then(null, onReject);
};
}
function resolvePromise(promise2, x, resolve, reject) {
if (x === promise2) {
return reject(new TypeError("Chaining cycle detected for promise"));
}
let called;
if (x != null && (typeof x === "object" || typeof x === "function")) {
try {
let then = x.then;
if (typeof then === "function") {
then.call(
x,
y => {
if (called) return;
called = true;
resolvePromise(promise2, y, resolve, reject);
},
err => {
if (called) return;
called = true;
reject(err);
}
);
} else {
resolve(x);
}
} catch (e) {
if (called) return;
called = true;
reject(e);
}
} else {
resolve(x);
}
}
第六步: promise实例 then的多次调用 堆栈处理
promise的实例 在同一级别可以调用多个then 所以我们要把resolve回调用数组的形式储存

const PENDING = "pending";
const FULFILLED = "fullilled";
const REJECTED = "rejected";
class PromiseDemo {
constructor(executor) {
this.state = PENDING;
this.resolveResult = undefined;
this.rejectResult = undefined;
this.onResolve = [];
this.onReject = [];
let resolve = value => {
if (this.state === PENDING) {
this.state = FULFILLED;
this.resolveResult = value;
// 把resolve回调用数组的形式储存
this.onResolve.forEach(fn=>fn());
}
};
let reject = reason => {
if (this.state === PENDING) {
this.state = REJECTED;
this.rejectResult = reason;
this.onReject.forEach(fn=>fn());
}
};
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
then = (onResolve, onReject) => {
const promise2 = new PromiseDemo((resolve, reject) => {
switch (this.state) {
case PENDING:
// 把resolve回调用数组的形式储存
this.onResolve.push(() => {
setTimeout(() => {
try {
const fulfilledResult = onResolve(this.resolveResult);
resolvePromise(fulfilledResult, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
});
this.onReject.push(() => {
setTimeout(() => {
try {
const rejectedResult = onReject(this.rejectResult);
resolvePromise(rejectedResult, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
});
break;
case FULFILLED:
setTimeout(() => {
try {
const fulfilledResult = onResolve(this.resolveResult);
resolvePromise(promise2, fulfilledResult, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
break;
default:
setTimeout(() => {
const rejectedResult = onReject(this.rejectResult);
resolvePromise(promise2, rejectedResult, resolve, reject);
}, 0);
break;
}
});
return promise2;
};
catch = onReject => {
this.then(null, onReject);
};
}
function resolvePromise(promise2, x, resolve, reject) {
if (x === promise2) {
return reject(new TypeError("Chaining cycle detected for promise"));
}
let called;
if (x != null && (typeof x === "object" || typeof x === "function")) {
try {
let then = x.then;
if (typeof then === "function") {
then.call(
x,
y => {
if (called) return;
called = true;
resolvePromise(promise2, y, resolve, reject);
},
err => {
if (called) return;
called = true;
reject(err);
}
);
} else {
resolve(x);
}
} catch (e) {
if (called) return;
called = true;
reject(e);
}
} else {
resolve(x);
}
}
const p = new PromiseDemo((resolve, reject) => {
setTimeout(() => {
console.log("log: promise");
resolve();
}, 0);
});
p.then(() => {
console.log("log: promise1");
});
p.then(() => {
console.log("log: promise2");
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log("log: 真实promise");
resolve();
}, 0);
});
p2.then(() => {
console.log("log: 真实promise1");
});
p2.then(() => {
console.log("log: 真实promise2");
});
第七步: promise的其他方法 —— promise完成
promise.all 等到所有结果返回 再调用resolve
PromiseDemo.all = (promises) =>{
let results = [];
function processResult (data,index,res) {
results.push(data);
if(promises.length === (index + 1)){
res(results)
}
}
return new Promise((res,rej)=>{
try{
promises.forEach((promise,index)=>{
promise.then((result)=>{
processResult(result,index,res)
})
})
}catch(e){
rej(e)
}
})
}
promise.race 等到第一个结果就调用resolve
PromiseDemo.race = (promises) =>{
function processResult (data,res) {
if(data){
res(data)
}
}
return new Promise((res,rej)=>{
try{
promises.forEach((promise)=>{
promise.then((result)=>{
processResult(result,res)
})
})
}catch(e){
rej(e)
}
})
}
async 函数的实现原理
阮一峰 es6里就有讲
async function fn(args) {
// ...
}
// 等同于
function fn(args) {
return spawn(function* () {
// ...
});
}
function spawn(genF) {
return new Promise(function(resolve, reject) {
const gen = genF();
function step(nextF) {
let next;
try {
next = nextF();
} catch(e) {
return reject(e);
}
if(next.done) {
return resolve(next.value);
}
Promise.resolve(next.value).then(function(v) {
step(function() { return gen.next(v); });
}, function(e) {
step(function() { return gen.throw(e); });
});
}
step(function() { return gen.next(undefined); });
});
}