//不加async await
function foo () {
Promise.resolve().then(resolve => {
console.log("1");
});
console.log(3);
}
foo();//3 1
//加了async await
async function foo () {
await Promise.resolve().then(resolve => {
console.log("1");
});
console.log(3);
}
foo();//1 3
async函数可能包含0个或者多个await表达式。await表达式会暂停整个async函数的执行进程并出让其控制权,只有当其等待的基于promise的异步操作被兑现或被拒绝之后才会恢复进程。promise的解决值会被当作该await表达式的返回值。使用async / await关键字就可以在异步代码中使用普通的try / catch代码块。
async/await 是ES6 引入的新语法,用来简化 Promise 异步操作。在async/await出现之前,开发者只能通过.then()链式方式处理Promise异步操作。
原因:.then()链式调用虽然解决了回调地狱的问题,但是存在代码冗余、阅读性差、不易理解。
相同点:
Promise和 async-await 都是优化异步编程体验的解决方案。
不同点:
async-await 是 Promise的补充(async函数会返回一个promise对象,用try-catch 捕获,也可以await 一个promise对象),可以让用户像编写同步代码一样编写异步代码,可以通过try-catch 捕获异常。
async/await是promise的语法糖
Promise 更多应用在函数封装中,async用在函数的使用中。
Promise链式调用相当于一个新的回调地狱, 也不能统一处理异常。 Promise 本身是同步函数,then才是回调函数,异步处理。
async-await相对于promise来讲写法使得可读性更强, 有明确的前后关系。
try/catch 语句捕获同步任务产生的错误。
Promise catch() 方法捕获异步任务产生的错误。
async 关键字声明的异步函数,在经过 await 关键字处理后,抛出的错误可以被 try/catch 语句捕获
try/catch和Promise.catch捕捉错误的区别
Promise和定时器同步异步相关实例,见代码:
console.log(1);
new Promise((resolve,reject)=>{
console.log(2); //Promise 本身是同步函数,then/catch才是回调函数,异步处理。
setTimeout(() => {
console.log(3); //宏任务里会先把微任务执行完再执行宏任务
}, 0);
for (let i = 0; i < 1000; i++) {
resolve()
}
reject() //已经先resolve了,已经处于一个状态,再reject也没用了
console.log(4); //Promise本身是同步函数,then/catch才是回调函数,异步处理。
}).then(()=>{
console.log(5);
}).catch(()=>{
console.log(7);
})
setTimeout(() => { //等上面一个Promise微任务里没有任何任务后,就继续查找下一个宏任务
(function(){
console.log(6);
})()
}, 0);
//1 2 4 5 3 6
Promise.resolve(8).then((res) => console.log(res)).
then((res) => console.log(res)).
catch(() => console.log(4));
console.log(1);
//1, 8, undefined 先执行1再执行Promise对象resolve返回的回调函数,第一个then接收完参数res,第二个then接收不到
const promise = new Promise((resolve, reject) => {
console.log(1);
setTimeout(() => { console.log("begin");
resolve("suss");
console.log("end"); }, 0);
console.log(2);
});
promise.then((data) => { console.log(data); });
console.log(4);
//1 2 4 begin end suss
console.log('1: script start');
setTimeout(() => {
console.log('2: setTimeout1'); //定时器1比定时器2先执行,因为代码是按自上而下顺序执行的,所以定时器1会先被添加到任务队列中,继而下一次查找宏任务会首先调用定时器1
new Promise((resolve) => {
console.log('3: promise1');
resolve();
}).then(() => {
console.log('4: then1')
})
});
new Promise((resolve) => {
console.log('5: promise2')
resolve();
}).then(() => {
console.log('6: then2');
setTimeout(() => {
console.log('7: setTimeout2')
})
})
console.log('8: script end')
附:
var time=setTimeout(() => {
console.log(555);
}, 1000);
console.log(time); //1 定时器方法的返回值是一个唯一的id,用于清除定时器
附:
前端代码异常:
一般语法错误以及运行时错误,浏览器都会在console里边体现出错误信息,以及出错的文件,行号,堆栈信息。
前端代码异常指的是以下两种情况:
1、JS脚本里边存着语法错误;
2、JS脚本在运行时发生错误。
那么我们如何去捕获这种异常呢,有两种方法:
第一种是try.catch,只能捕捉运行时的错误
第二种是 window.onerror,可以捕捉到全局的错误事件(对于跨域的JS资源,window.onerror拿不到详细的信息,需要解决跨域)