首页 > 其他 > 详细

promise async await 基本用法和面试题详解

时间:2019-12-13 11:51:20      阅读:499      评论:0      收藏:0      [点我收藏+]

导语:异步编程的最高境界就是不关心它是否是异步。async、await很好的解决了这一点,将异步强行转换为同步处理。
async/await与promise不存在谁代替谁的说法,因为async/await是寄生于Promise,是Generater的语法糖。

 

温馨提示:如果你已经知道了关于async await的基本用法,请直接看分割线以下内容

Generator

 

1. 调用 Generator 函数,返回一个遍历器对象,代表 Generator 函数的内部指针。
2.  以后,每次调用遍历器对象的next方法,就会返回一个有着value和done两个属性的对象。
3.  value属性表示当前的内部状态的值,是yield表达式后面那个表达式的值;done属性是一个布尔值,表示是否遍历结束。
 
function* helloWorld () {
    yield ‘hello‘
    yield ‘world‘
    return ‘ending‘
}

var hw = helloWorld()
console.log(hw)         // helloWorld {<suspended>}
console.log(hw.next())  // {value: "hello", done: false}
console.log(hw.next())  // {value: "world", done: false}
console.log(hw.next())  // {value: "world", done: false}
console.log(hw.next())  // {value: undefined, done: true}

  

 

async
1. async其实就是对Generator的封装,只不过async可以自动执行next()。
2. async必须等到里面所有的await执行完,async才开始return,返回的Promise状态才改变。除非遇到return和错误。
3. async默认返回一个Promise,如果return不是一个Promise对象,就会被转为立即resolve的Promise,可以在then函数中获取返回值。
 
async function fn () {
    await 100
    await 200
    return 300
}
fn().then(res => {
    console.log(res) // 300
}) 
 
 再看下面这个例子:
技术分享图片

 打印结果如下:(返回的是promise对象)

技术分享图片

如果在async函数中抛出了错误,则终止错误结果,不会继续向下执行:

 技术分享图片

如果希望一个await失败,后面的继续执行,可以使用try...catch或者在await后面的Promise跟一个catch方法:
async function f() {
  try {
    await Promise.reject(‘出错了‘);
  } catch(e) {
  }
  return await Promise.resolve(‘hello world‘);
}

f()
.then(v => console.log(v))   // hello world

// catch
async function f() {
  await Promise.reject(‘出错了‘)
    .catch(e => console.log(e));   // 出错了
  return await Promise.resolve(‘hello world‘);
}

f()
.then(v => console.log(v))  // hello world

 

================================   分割线   ==================================

面试题

【例1】

async function async1() {
    console.log("async1 start");
    await async2();
    console.log("async1 end");
    return ‘async return‘;
}

async function async2() {
    console.log("async2");
}

console.log("script start");

setTimeout(function() {
    console.log("setTimeout");
}, 0);

async1().then(function (message) { console.log(message) });

new Promise(function(resolve) {
    console.log("promise1");
    resolve();
}).then(function() {
    console.log("promise2");
});

console.log("script end");

输出顺序如下:

技术分享图片

 [分析]:

1. 首先我们从上到下看,打印:script  start;

2. setTimeout 虽然是0,但依然要放到执行栈,等待后续执行。继续往下走;

3. async1 开始执行,当函数里遇到await时,暂停执行(await所在行放在本次执行完),执行完后遇到then是异步,此时async1被添加到任务队列

4.  new Promise() 实例对象被new出来后,它里面的promise1会立刻打印,然后又遇到then,此时promise对象被添加到任务队列

 

 【例2】:

var p = new Promise((res,rej) => {
    res(‘hello one‘)
    console.log(‘good morning‘)
})

function hello() {
    console.log(‘hello begins‘)
    return p
}

hello().then(res => {
    console.log(res)
    console.log(‘hello1111111111‘)
    return ‘hello two‘
}).then(res => {
    console.log(res)
    console.log(‘hello22222222222‘)
    return ‘hello three‘
}).then(res => {
    console.log(res)
    console.log(‘hello33333333333‘)
})

function test1 () {
    console.log(‘test1‘)
}

async function asy () {
    console.log(‘asy begins‘)
    await console.log(‘asy---111111‘)

    console.log(‘async1‘)
    await console.log(‘asy---222222‘)

    console.log(‘asy ends‘)
}

asy()

test1()

function* gnrt () {
    console.log(1)
    yield console.log(11111111)
    
    console.log(2)
    yield console.log(22222222)
    
    console.log(3)
    yield console.log(33333333)
}

var result = gnrt()
result.next()
result.next()
result.next()

输出顺序如下:

技术分享图片

promise async await 基本用法和面试题详解

原文:https://www.cnblogs.com/edwardwzw/p/12033935.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!