尽管任务3的延时为0s,但是异步操作会在同步任务全部执行完后,再执行。
里面的时间是确定多个异步任务的执行顺序的。
当任务4依赖于任务3的数据,就得把4写到3下面。当5依赖4,就得写到4下面。
当把log换成逻辑后,就会变成复杂的嵌套。
为了解决这个,es6推出promise
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
<script>
// setTimeout(() => {
// console.log(1);
// setTimeout(() => {
// console.log(2);
// setTimeout(() => {
// console.log(3);
// }, 1000)
// }, 1000)
// }, 1000)
const p1 = new Promise((resolve, reject) => {
resolve('任务1成功得到信息')
// reject('任务1失败')
})
p1.then(
data => {
console.log(data);
return new Promise((resolve, reject) => {
resolve('任务2成功得到信息')
// reject('任务2失败')
})
},
err => {
console.log(err);
return new Promise((resolve, reject) => {
resolve('任务3成功得到信息')
// reject('任务3失败')
})
}
)
.catch(err => {
console.log(err);
})
</script>
</html>
<script>
const p1 = new Promise((resolve, reject) => {
// resolve('任务一success');
reject('任务一fail');
})
p1.then(data => {
console.log(data);
// 第二个异步任务
return new Promise((resolve, reject) => {
resolve('任务二success');
reject('任务二fail');
})
}, err => {
console.log(err);
throw new Error('任务一失败');
}).then(data => {
console.log(data);
})
.catch(err => {
console.log(err);
})
</script>
任务一成功,任务二失败就会正常输出。
但是任务一失败后就会抛出Error,任务二也不会执行。
下面是使用async语法糖处理
function asyncTask() {
return new Promise((resolve, reject) => {
const isSuccess = true;
if (isSuccess) {
resolve('任务二异步任务成功');
} else {
reject('任务二异步任务失败');
}
})
}
// 步骤二:为使用await的函数添加async
async function main() {
console.log('任务一');
const data = await asyncTask();
console.log(data);
console.log('任务三');
}
main();
ES6还推出了Proxy代理
Model
promise三个状态:
无论是fulfilled还是reject,都要有下一步操作:
就诞生了then
执行下面的代码:
setTimeout(() => {
console.log("111");
}, 2000);
setTimeout(() => {
console.log("222");
}, 1000);
先输出222,再输出111.
这就是异步操作,后面的不会等待前面的执行完再执行。
升级一下,下面这个函数:
<script>
// 先定义两个函数
function drive(fn) {
setTimeout(() => {
fn();
}, 2000);
}
function shopping(fn) {
setTimeout(() => {
fn();
}, 1000);
}
(function func() {
drive(() => console.log('正在开车去超市'))
shopping(() => console.log('正在超市购物'))
})();
</script>
执行也是先执行短的,但是要想让他先开车,再购物,就要把购物写到开车里面。
<script>
// 先定义两个函数
function drive(fn) {
setTimeout(() => {
fn();
}, 2000);
}
function shopping(fn) {
setTimeout(() => {
fn();
}, 1000);
}
(function func() {
drive(() => {
console.log('正在开车去超市');
shopping(() => {
console.log('正在超市购物');
})
})
})();
</script>
这样就实现了预期的效果,但是如果想要完成的任务很多,就会产生复杂的嵌套
(function func() {
drive(() => {
console.log('正在开车去超市');
shopping(() => {
console.log('正在超市购物');
watchMovie(() => {
console.log('正在看电影');
eating(() => {
console.log('正在吃饭');
})
})
})
})
})();
这就是回调地狱,代码不直观,难以维护。
promise应运而生:
<script>
// 先定义两个函数
function drive() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('正在开车去超市')
}, 2000);
})
}
function shopping() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('正在超市购物')
}, 1000);
})
}
drive().then((data) => {
console.log(data);
return shopping();
}).then((data) => {
console.log(data);
});
</script>
两个函数返回值为promise对象,
然后调用drive()打印drive里面的promise的resolve,然后drive.then又执行返回shopping()里面的promise的resolve,然后外面的then再打印。
使用async、await更优雅的写法
<script>
// 先定义两个函数
function drive() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('正在开车去超市')
}, 2000);
})
}
function shopping() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('正在超市购物')
}, 1000);
})
}
(async function func() {
console.log(await drive());
console.log(await shopping());
})();
</script>
教室真冷。。。