const demo = new Promise((resolve,reject)=>{
resolve('sajdhgas')
})
demo.then(a =>{console.log(a,'console')})
复制代码
偷懒用的mdn的图,见谅啊,各位大佬 (- . -)javascript
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')})
复制代码
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内部加一个状态锁 statejava
对于异步: 在等待过程当中,把onResolve存起来,在resolve回调里处理调用
对于同步: 在执行executor的时候把resolve的值存起来,在then里直接调用es6
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");
});
复制代码
then方法和catch方法 都返回一个新的 promise对象,Promise 对象的错误具备“冒泡”性质,会一直向后传递,直到被捕获为止。json
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");
});
复制代码
功能:数组
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 链式调用顺序 结果代码报错
这里涉及到一个知识点 —— 链式调用顺序promise
由于在同一个then内的回调callback都是被异步调用的, 因此同一级的then中先调用最外层then再向内层依次执行异步
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
复制代码
下面是完整代码async
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 因此咱们要把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.all 等到全部结果返回 再调用resolvepost
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)
}
})
}
复制代码
阮一峰 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); });
});
}
复制代码