目录
1. 同步和异步
同步和异步是一种消息通知机制,而阻塞是对主体而言的
- 同步阻塞: A调用B,B处理获得结果,才返回给A。A在这个过程中,一直等待B的处理结果,没有拿到结果之前,需要A(调用者)一直等待和确认调用结果是否返回,拿到结果,然后继续往下执行。
( 做一件事,没有拿到结果之前,就一直在这等着,一直等到有结果了,再去做下边的事) - 异步非阻塞: A调用B,无需等待B的结果,B通过状态,通知等来通知A或回调函数来处理。
(做一件事,不用等待事情的结果,然后就去忙别的了,有了结果,再通过状态来告诉我,或者通过回调函数来处理。)
2. promise
2-1. 三种状态
- padding
- resolved/fulfilled(火狐) —— 调用resolve()
- rejected —— 调用reject()
2-2. then方法
- 接收2个参数:onresolved 和 onrejected;
let p = new Promise((resolve, reject) => {
resolve("success");
// reject("error");
});
p.then(function (res) {
console.log("成功回调", res);
}, function (err) {
console.log("失败回调",err);
})
>成功回调 success
- 三种返回值:
-由于一直返回promise对象,因此可以进行链式操作p.then. … .then()
- 无返回值——默认返回 resolved状态 promise对象;
let p = new Promise((resolve, reject) => {
resolve("success");
});
console.log(p);
let p2 = p.then(function (res) {
});
console.log(p2);
>Promise {<resolved>: "success"}
>__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: "success"
>Promise {<pending>}
>__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: undefined
- 返回非promise对象 —— 默认返还 resolved状态 promise对象 传参;
let p = new Promise((resolve, reject) => {
resolve("success");
});
let p2 = p.then(function () {
return 1111;
});
console.log(p2);
>Promise {<pending>}
>__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: 1111
let p = new Promise((resolve, reject) => {
resolve("success");
});
let p2 = p.then(function () {
return 1111;
}).then(function(res){
console.log(res);
});
console.log(p2);
>Promise {<pending>}
>__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: undefined
>1111
- 直接return promise对象
let p = new Promise((resolve, reject) => {
resolve("success");
});
let p2 = p.then(function () {
return new Promise((resolve, reject) => {
resolve();
});
});
console.log(p2);
console.log(p2);
>Promise {<pending>}
>__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: undefined
2-3. 通过promise实现回调函数
// 通过then的链式操作可以避免回调地狱的出现
function loadImg() {
return new Promise((resolve, reject) => {
let img = new Image();
img.src = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1601011752925&di=80136ef6bf70f419b7c3738fbeabe730&imgtype=0&src=http%3A%2F%2Fdl.ppt123.net%3A81%2Fpptbj%2F201203%2F2012030708111341.jpg";
// img.src = "https://www.baidu.com/link?ur";
img.onload = function () {
resolve("图片加载完成");
}
img.onerror = function () {
reject("图片加载失败");
}
})
}
// 将回调放入then
loadImg().then(res => {
console.log(res);
console.log("成功后的逻辑");
}, rej => {
console.log(rej);
console.log("失败后的逻辑");
})
>图片加载完成
>成功后的逻辑
- catch存在返回值,返回值参照then的方法,返回的是promise对象,仍然可以继续then()
let p = function () {
return new Promise(resolve, reject) {
if () {
resolve();
} else {
reject();
}
}
}
p.then(res => {
}).then(res => {
}).catch(err => {
console.log("catch返回值与then方法类似");
})
2-4. Promise.resolve()和Promis.reject()
- Promise.resolve() —— 返还一个状态为resolved的promise对象
- Promise.reject() —— 返还一个状态为rejected的promise对象
let p = new Promise((resolve) => {
resolve("success");
});
let p2 = p.then(() => {
return Promise.reject();
});
console.log(p2);
>Promise {<pending>}
>__proto__: Promise
[[PromiseStatus]]: "rejected"
[[PromiseValue]]: undefined
2-5. Promise.all() — 同时执行
- 使用Promise.all()时,所有的promise都必须是resolve才能在then中获取res的结果
let p1 = new Promise((resolve) => {
setTimeout(() => {
console.log(1);
resolve("success1");
})
});
let p2 = new Promise((resolve) => {
setTimeout(() => {
console.log(2);
resolve("success2");
})
});
let p3 = new Promise((resolve) => {
setTimeout(() => {
console.log(3);
resolve("success3");
})
});
Promise.all([p1, p2, p3]).then(res => {
console.log(res);
})
>1
>2
>3
>(3) ["success1", "success2", "success3"]
- 当出现reject()时
let p1 = new Promise((resolve) => {
setTimeout(() => {
console.log(1);
resolve("success1");
})
});
let p2 = new Promise((resolve) => {
setTimeout(() => {
console.log(2);
// resolve("success2");
reject();
})
});
let p3 = new Promise((resolve) => {
setTimeout(() => {
console.log(3);
resolve("success3");
})
});
Promise.all([p1, p2, p3]).then(res => {
console.log(res);
})
>1
>2
>index.html:25 Uncaught ReferenceError: reject is not defined
at index.html:25
>3
2-6. Promise.race() —— 按执行快慢获取结果
let p1 = new Promise((resolve) => {
setTimeout(() => {
console.log(1);
resolve("success1");
}, 2000)
});
let p2 = new Promise((resolve) => {
setTimeout(() => {
console.log(2);
resolve("success2");
}, 1000)
});
let p3 = new Promise((resolve) => {
setTimeout(() => {
console.log(3);
resolve("success3");
}, 3000)
});
Promise.race([p1, p2, p3]).then(res => {
console.log(res);
});
>2
>success2[由于执行速度快,所以首先获得]
>1
>3
2-7. 不需要按顺序执行:Promise.all()、Promise.race()
3. ES7:async和await — 异步函数,同步写法
- async首先声明一个异步函数
- await后边要跟着一个promise对象
async function myfn() {
// await后边一定要跟一个promise对象
await new Promise((resolve, reject) => {
setTimeout(() => {
console.log(1);
resolve();
// 若是reject()则不会往下执行
}, 1000);
});
await new Promise((resolve, reject) => {
setTimeout(() => {
console.log(2);
resolve();
}, 4000);
});
await new Promise((resolve, reject) => {
setTimeout(() => {
console.log(3);
resolve();
}, 1000);
});
}
myfn();
>1(1s后出现)
>2(再过4s后出现)
>3(再过1s后出现)
- 若出现reject()可以通过try(){}catch(){}捕获
async function myfn() {
// await后边一定要跟一个promise对象
try {
await new Promise((resolve, reject) => {
setTimeout(() => {
console.log(1);
// resolve();
reject("错误");
// 若是reject()则不会往下执行
}, 1000);
});
await new Promise((resolve, reject) => {
setTimeout(() => {
console.log(2);
resolve();
}, 4000);
});
await new Promise((resolve, reject) => {
setTimeout(() => {
console.log(3);
resolve();
}, 1000);
});
}catch(err){
console.log(err);
}
}
myfn();
>1
>错误
- await 的接收的值即resolve(res)中的res
let p = new Promise((resolve, reject) => {
resolve("success");
});
async function fn(){
let c = await p;
console.log(c);
}
fn();
>success