当笔记本慢慢记录了
JavaScript为什么要出现promise与async
处理异步的三种方法
红绿灯
公共代码
js
题目:红灯三秒亮一次,绿灯一秒亮一次,黄灯两秒亮一次,不断交替循环
function red() {
console.log("red");
}
function green() {
console.log("green");
}
function yellow() {
console.log("yellow");
}
setTimeOut实现红绿灯
js
var light = (time, cb) => {
setTimeout(cb, time);
};
function step() {
light(3000, () => {
red();
light(1000, () => {
green();
light(2000, () => {
yellow();
step();
});
});
});
}
step();
promise实现红绿灯
js
var light = (timmer, cb) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
cb();
resolve();
}, timmer);
});
};
var step = () => {
new Promise((resolve)=>resolve())
.then(() => {
return light(3000, red);
})
.then(() => {
return light(1000, green);
})
.then(() => {
return light(2000, yellow);
})
.then(() => {
step();
})
.catch(err => console.log(err));
};
step();
async awiat
js
const light = (timmer, cb) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
cb();
resolve();
}, timmer);
});
};
async function step() {
await light(3000, red);
await light(1000, green);
await light(2000, yellow);
step();
}
step();
手写promise
promise如何使用
js
const p0 = new Promise((resolve, reject) => {
resolve(1);
});
p0.then(
(res) => {console.log(res)},
(err) => {console.log(err)}
);
简单实现
js
function _Promise(fn){
let _self=this
_self.state='pending'
_self.resolveAns
_self.rejectAns
function resolve(res){
if(_self.state=='pending'){
_self.state='resolve'
_self.resolveAns=res
}
}
function reject(res){
if(_self.state=='pending'){
_self.state='reject'
_self.rejectAns=res
}
}
try {
fn(resolve,reject)
} catch (error) {
reject(error)
}
}
_Promise.prototype.then=function(onResolve,onReject){
let _self=this
switch (_self.state) {
case 'resolve':
onResolve(_self.resolveAns)
break;
case 'reject':
onReject(_self.rejectAns)
break;
default:
break;
}
}
let p=new _Promise((resolve,reject)=>{
resolve(1)
})
p.then((res)=>{
console.log(res);
})
异步实现
js
function _promise(fn) {
let _self = this;
_self.state = "pending";
_self.resolveAns;
_self.rejectAns;
_self.resolveAnsFn = [];
_self.rejectAnsFn = [];
function resolve(res) {
if (_self.state == "pending") {
_self.resolveAns = res;
_self.state = "resolve";
_self.resolveAnsFn.forEach((fn) => fn(res));
_self.resolveAnsFn = [];
}
}
function reject(res) {
if (_self.state == "pending") {
_self.rejectAns = res;
_self.state = "reject";
_self.rejectAnsFn.forEach((fn) => fn(res));
_self.rejectAnsFn = [];
}
}
try {
fn(resolve, reject);
} catch (error) {
reject(error);
}
}
_promise.prototype.then = function (resolveFn, rejectFn) {
let _self = this;
switch (_self.state) {
case "resolve":
resolveFn(_self.resolveAns);
break;
case "reject":
rejectFn(_self.rejectAns);
break;
case "pending":
_self.resolveAnsFn.push(resolveFn);
_self.rejectAnsFn.push(rejectFn);
break;
default:
break;
}
};
let p = new _promise((resolve, reject) => {
setTimeout(() => {
resolve('111')
}, 2000);
});
p.then((res) => {
console.log(res);
});
链式调用
js
// 自定义的Promise构造函数,用于模拟Promise的基本功能
function _Promise(fn) {
const _self = this;
_self.status = "pending";
_self.resolveAns = undefined;
_self.rejectAns = undefined;
_self.resolveCallback = [];
_self.rejectCallback = [];
function resolve(res) {
if (_self.status === "pending") {
_self.status = "resolve";
_self.resolveAns = res;
_self.resolveCallback.forEach((fn) => fn());
_self.resolveCallback = [];
}
}
function reject(err) {
if (_self.status === "pending") {
_self.status = "reject";
_self.rejectAns = err;
_self.rejectCallback.forEach((fn) => fn());
_self.rejectCallback = [];
}
}
try {
fn(resolve, reject);
} catch (e) {
reject(e);
}
}
_Promise.prototype.then = function (resolveFn, rejectFn) {
const _self = this;
return new _Promise((resolve, reject) => {
const callback = (fn) => {
try {
const result = fn(_self.resolveAns || _self.rejectAns);
resolve(result);
} catch (e) {
reject(e);
}
};
switch (_self.status) {
case "resolve":
callback(resolveFn);
break;
case "reject":
callback(rejectFn);
break;
case "pending":
_self.resolveCallback.push(() => callback(resolveFn));
_self.rejectCallback.push(() => callback(rejectFn));
break;
default:
break;
}
});
};
const p0 = new _Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 1000);
});
p0.then((res) => {
console.log("监听p0 resolve状态的返回值", res);
return res + 1;
}).then((res) => {
console.log("监听p1 resolve状态的返回值", res);
}).then((res)=>{
console.log(res);
})
修复then状态同步
js
// 自定义的Promise构造函数,用于模拟Promise的基本功能
function _Promise(fn) {
const _self = this;
_self.status = "pending";
_self.resolveAns = undefined;
_self.rejectAns = undefined;
_self.resolveCallback = [];
_self.rejectCallback = [];
function resolve(res) {
if (_self.status === "pending") {
_self.status = "resolve";
_self.resolveAns = res;
_self.resolveCallback.forEach((fn) => fn());
_self.resolveCallback = [];
}
}
function reject(err) {
if (_self.status === "pending") {
_self.status = "reject";
_self.rejectAns = err;
_self.rejectCallback.forEach((fn) => fn());
_self.rejectCallback = [];
}
}
try {
fn(resolve, reject);
} catch (e) {
reject(e);
}
}
_Promise.prototype.then = function (resolveFn, rejectFn) {
const _self = this;
return new _Promise((resolve, reject) => {
const callback = (fn) => {
try {
const result = fn(_self.resolveAns || _self.rejectAns);
if (result instanceof _Promise) {
result.then(
(res) => resolve(res),
(err) => reject(err)
);
return;
}
resolve(result);
} catch (e) {
reject(e);
}
};
switch (_self.status) {
case "resolve":
callback(resolveFn);
break;
case "reject":
callback(rejectFn);
break;
case "pending":
_self.resolveCallback.push(() => callback(resolveFn));
_self.rejectCallback.push(() => callback(rejectFn));
break;
default:
break;
}
});
};
const p0 = new _Promise((resolve, reject) => resolve());
p0.then((res) => {
return new _Promise((resolve, reject) =>
reject("p1 的 onResolved 里返回了新的 Promise,其状态是 rejected")
);
}).then(
(res) => {
console.log("监听p1 resolved 状态的返回值");
console.log(res);
},
(e) => {
console.log("监听p1 rejected 状态的返回值");
console.log(e);
}
);
手写promiseAPI
all
js
Promise._all = function (promises) {
let arr = [];
return new Promise((resolve, reject) => {
promises.forEach((item, i) => {
Promise.resolve(item).then(
(res) => {
arr[i] = res;
if (arr.length === promises.length) resolve(arr);
},
(e) => reject(e)
);
});
});
};
let p1 = Promise.resolve("1");
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("p2 延时一秒");
}, 1000);
});
Promise._all([p1, p2]).then((res) => console.log(res));
any
js
Promise._any = function (promises) {
count = 0;
return new Promise((resolve, reject) => {
promises.forEach((item, i) => {
Promise.resolve(item).then(
(e) => resolve(e),
(err) => {
count += 1;
if (count === promises.length)
reject(new Error("没有promise成功"));
}
);
});
});
};
race
js
Promise._race = function (promiseArray) {
return new Promise((resolve, reject) => {
promiseArray.forEach(p => {
Promise.resolve(p).then((res) => resolve(res), (err) => reject(err));
})
});
}
let p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("p3 延时一秒");
}, 100);
});
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("p2 延时一秒");
}, 1000);
});
Promise._race([p3, p2]).then((res) => console.log(res));
手写async await
async
js
function reqData(url) {
return new Promise((res, rej) => {
setTimeout(() => {
res(url);
}, 2000);
});
}
function* getData() {
const r1 = yield reqData("why");
console.log("r1:", r1);
const r2 = yield reqData(r1 + "kobe");
console.log("r2:", r2);
const r3 = yield reqData(r2 + "james");
console.log("r3:", r3);
}
const generator = getData()
generator.next().value.then(res1 => {
generator.next(res1).value.then(res2 => {
generator.next(res2).value.then(res3 => {
generator.next(res3)
})
})
})
function exec(genFn) {
const gen = genFn();
function run(res) {
const { done, value } = gen.next(res);
if (done) return;
value.then((res) => {
run(res);
});
}
run();
}
exec(getData);