今天我们来详细了解一下另外两种的处理异步同步化的方法。
先来看一个实例。
// 使得下面代码按照p2, p1的顺序打印
let p1 = function () {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('p1');
resolve('p1');
}, 1000)
})
}
let p2 = function () {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('p2');
resolve('p2');
}, 2000)
})
}
回调函数
p2();
setTimeout(() => [
p1()
])
Promise
p2().then(() => {
p1();
})
generator函数
function* gen() {
yield p2();
yield p1();
}
let g = gen();
g.next();
g.next();
// 但是无法完成上述的任务
async/await
async function asy1() {
let p1 = await p2();
console.log(p2); // p2
let p2 = await p1();
console.log(p1); // p1
}
generator 函数
接下来举个例子来详细说明一下generator函数的用法:
function* gen1() {
// 1. yield 需要 next() 执行
// 2. 阻止下面的代码执行
// 3. 后面的内容为返回值,通过value获取
yield 1;
console.log('gen1');
yield 2;
console.log('gen2');
return 123;
yield 3; // return 下的所有 yield 不能执行了
}
let g1 = gen1();
console.log(g1);
console.log(g1.next().value); // 获取第一个yield 的返回值
console.log(g1.next().value); // 获取第二个yield 的返回
console.log(g1.next().value); // 获取第三个yield 的返回
console.log(g1.next().value); // 获取第四个yield 的返回
async/await
- 在普通函数前面加上关键字async 就是async函数
- await 只能在async中使用
- await 后面必须赋值promise 实例(可以是new,.then, return, all, async)
- await 的返回值 相当于 then 的回参赋值(关键看await 后promise 是如何产生的)
- resolve
- then 中 return
- 返回 return await 的返回结果。需要用await接受
如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。
如果它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。
//它就是 Generator 函数的语法糖。
function delay(data) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(data);
},1000)
})
}
async function a() {
try{
const p1 = await delay('1')
console.log(p1);
const p2 = await delay('2')
console.log(p2);
const p3 = await delay('3')
console.log(p3);
}catch(err){
console.log('这里可以捕获到try 中执行的错误', err);
}
}
// a();
为啥说async/await的是非常有用的,在处理事件的时候需要用到上一个的数据的时候它的作用就有体现了。
// 实例
function takeLongTime(arr) {
return arr.reduce((pre, sum) => {
return pre + sum
},0);
}
function step1(n) {
console.log(`step1 with ${n}`);
return takeLongTime([n]);
}
function step2(m, n) {
console.log(`step2 with ${m} and ${n}`);
return takeLongTime([m,n]);
}
function step3(k, m, n) {
console.log(`step3 with ${k}, ${m} and ${n}`);
return takeLongTime([k,m,n]);
}
async function doIt() {
console.time('doIt');
const time = 300;
const time1 = await step1(time);
const time2 = await step2(time, time1);
const result = await step3(time, time1 ,time2);
console.log(`result is ${result}`);
console.timeEnd('doIt');
}
doIt();
// 运行结果
step1 with 300
25.async&await.html:69 step2 with 300 and 300
25.async&await.html:73 step3 with 300, 300 and 600
25.async&await.html:83 result is 1200
25.async&await.html:84 doIt: 0.868896484375 ms