创建Promise
异步执行,先请求完
接口1
,再拿接口1
返回的数据,去当做接口2
的请求参数
const promise = (num) => {
return new Promise(function (resolve, reject) {
console.log(6)
resolve(num * 2);
});
};
const handleClick = () => {
console.log(1);
setTimeout(() => {
console.log(2);
});
promise(3)
.then((arg) => {
console.log(arg)
promise(arg).then((arg) => console.log(arg));
})
console.log(5);
};
执行顺序 1 6 5 6 6 12 2
使用async/await
await后面接Promise
const handleClick = (() => {
function request(num) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(num * 2)
}, 2000)
})
}
async function fn() {
let aaa = await request(1)
// 等待2秒
console.log(aaa)
let bbb = await request(aaa)
// 再等待2秒
console.log(bbb)
}
fn()
})
await后面不接Promise
const handleClick = (() => {
function request(num) {
return num * 2
}
async function fn() {
// 几乎同时打印,但能拿到aaa的结果作为参数
let aaa = await request(1)
console.log(aaa)
let bbb = await request(aaa)
console.log(bbb)
}
fn()
})
如果
await
后面接的不是Promise
的话,有可能其实是达不到排队
的效果的
async
是一个位于function之前的前缀,只有async函数
中,才能使用await
async函数
执行完会自动返回一个状态为fulfilled
的Promise,也就是成功状态,但是值却是undefined,那要怎么才能使值不是undefined呢?很简单,函数有return
返回值就行了
async function fn (num) {
return num
}
console.log(fn) // [AsyncFunction: fn]
console.log(fn(10)) // Promise {<fulfilled>: 10}
fn(10).then(res => console.log(res)) // 10
generator函数拓展
基本用法
generator函数
跟普通函数在写法上的区别就是,多了一个星号*
,并且只有在generator函数
中才能使用yield
,什么是yield
呢,他相当于generator函数
执行的中途暂停点
,比如下方有3个暂停点。而怎么才能暂停后继续走呢?那就得使用到next方法
,next方法
执行后会返回一个对象,对象中有value 和 done
两个属性
- value:暂停点后面接的值,也就是yield后面接的值
- done:是否generator函数已走完,没走完为false,走完为true
function* gen() {
yield 1
yield 2
yield 3
return 4
}
const g = gen()
console.log(g.next()) // { value: 1, done: false }
console.log(g.next()) // { value: 2, done: false }
console.log(g.next()) // { value: 3, done: false }
console.log(g.next()) // { value: 4, done: true }
实现具有async功能的函数
function foo(num) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(num * 2);
}, 1000);
});
}
function generatorToAsync(generatorFn) {
return function() {
const gen = generatorFn.apply(this, arguments) // gen有可能传参
// 返回一个Promise
return new Promise((resolve, reject) => {
function go(key, arg) {
let res
try {
res = gen[key](arg) // 这里有可能会执行返回reject状态的Promise
} catch (error) {
return reject(error) // 报错的话会走catch,直接reject
}
// 解构获得value和done
const { value, done } = res
if (done) {
// 如果done为true,说明走完了,进行resolve(value)
return resolve(value)
} else {
// 如果done为false,说明没走完,还得继续走
// value有可能是:常量,Promise,Promise有可能是成功或者失败
return Promise.resolve(value).then(val => go('next', val), err => go('throw', err))
}
}
go("next") // 第一次执行
})
}
}
function* gen() {
const num1 = yield foo(1);
const num2 = yield foo(num1);
const num3 = yield foo(num2);
return num3;
}
const asyncFn = generatorToAsync(gen);
const asyncFn = generatorToAsync(gen)
asyncFn().then(res => console.log(res))