基本用法
async函数
async定义的函数返回一个Promise对象,可以使用then方法添加回调函数。
async function timeout() { return 'hello world' } console.log(timeout()); console.log('虽然在后面,但是我先执行');
它和promise一样,有异步回掉功能
async function timeout() { return 'hello world' } timeout().then(result => { console.log(result); }) console.log('虽然在后面,但是我先执行');
async原理:如果async成功返回一个promise对象,实际会调用Promise.resolve()返回,否则会调用Promise.reject()
async function timeout(flag) { if (flag) { return 'hello world' } else { throw 'my god, failure' } } console.log(timeout(true)) // 调用Promise.resolve() 返回promise 对象。 console.log(timeout(false)); // 调用Promise.reject() 返回promise 对象。
await
当函数执行时,一旦遇到await(后面定义的也是一个promise对象)就会先返回,等异步操作完成,再执行后面的语句。
await只能出现在async函数内部,等待async函数返回或执行promise,
// 2s 之后返回双倍的值
function doubleAfter2seconds(num) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2 * num)
}, 2000);
} )
}
async function testResult() {
let result = await doubleAfter2seconds(30);
console.log(result);
}
testResult(); //2s后输出60
代码执行过程:
- 调用testResult()函数,遇到await,开始等待(后面的promise执行完毕)
- 执行await后的doubleAfter2seconds(30),返回promise开始执行,2s后执行完毕,值为60并返回
- await拿到60,赋值给result,等待结束,代码继续运行,执行console
这里如果计算多个值,可以像写同步代码那样,避免回掉地狱
async function testResult() {
let first = await doubleAfter2seconds(30);
let second = await doubleAfter2seconds(50);
let third = await doubleAfter2seconds(30);
console.log(first + second + third);
}
demo
- 获取股票报价的函数(可以用.then处理async函数)
async function getStockPriceByName(name) {
const symbol = await getStockSymbol(name);
const stockPrice = await getStockPrice(symbol);
return stockPrice;
}
getStockPriceByName('goog').then(function (result) {
console.log(result);
});
- 在api中,把结果return 出去
export async function getRetailUnitPrice () {
const reqBody = await get('/race/spot/racespot/enter/dayahead')
return reqBody
}
注意点
- async函数返回的promise对象,必须等到内部所有await命令后面的对象执行完,才会执行then
- 当async返回一个常量,返回Promise.resolve(常量)自动构建promise返回值
- 当async函数没有返回值的时候,返回Promise.resolve(undefiend)自动构建promise返回值
async function getTitle(url) {
let response = await fetch(url);
let html = await response.text();
return html.match(/<title>([\s\S]+)<\/title>/i)[1];
}
getTitle('https://tc39.github.io/ecma262/').then(console.log)
// "ECMAScript 2017 Language Specification"
与promise相比
优点:处理.then链,不必把回掉嵌套在.then中,只要await即可
function sing() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(`来一首好听的歌吧~~~`);
}, 1000);
});
}
async function demo() {
try {
const v = await say();
const s = await sing();
console.log(v); // 输出:hello, joel。今年我 26 岁
console.log(s) // 来一首好听的歌吧~~~
} catch (e) {
console.log(e)
}
}
demo();
如果使用原来的Promise 就是把回调放在then()中。