Promise、async、await

122 阅读2分钟

首先理清几个概念

  1. JS是单线程语言,JS诞生的用途是为了操作DOM以及与用户的交互,因此只能是单线程,多个线程同时操作一个dom时不合理的
  2. 同步和异步:能直接拿到结果的是同步,不能直接拿到结果的就是异步
  • 同步
function second(){
  console.log('2')
}
function first(){
  console.log('1')
  second()
  console.log('3')
}
first()
/*
"1"
"2"
"3"
*/
  • 异步
const getList = () => {
    setTimeout(() => {
        console.log(2);
    }, 2000);
};
console.log(1);
getList();
console.log(3);

//1 3 2
  1. 调用栈:js执行代码时会将函数进行以队列(后进先出)的形式压栈,执行完毕就弹栈
  2. web worker标准允许js可以创建多个线程,但是子线程完全受主线程控制,且不得操作dom,不影响js单线程的本质
  3. 消息队列:同步执行代码的时候,会有一个“执行栈”,开启多线程时,浏览器还会维护一个消息列表,执行栈执行主线程,消息列表是副线程(异步)的集合
  4. 宏任务、微任务:宏任务是同步流程中出现的的代码,setTimeout、setInterval、setImmediate、I/O等。

代表性的微任务如promise.then catch finally、process.nextTick(node环境)\ MutationObserver等

  1. 事件轮询(EventLoop):主线程优先执行,主线程执行完后执行消息列表(副线程),这都是在执行宏任务。当碰到有微任务,执行完微任务才会执行下一个宏任务

promise

Promise

在async和await之前,还需要了解Generator函数

Generator函数最大特点是可以交出函数的执行权(暂停执行)

next()一下走一步

function* doWhat(){
  yield '吃饭'
  return '睡觉'
}
let man=doWhat()
console.log(man.next())
console.log(man.next())
/*
{
  done: false,
  value: "吃饭"
}
{
  done: true,
  value: "睡觉"
}
*/
  • function* xxxfunction *xxx一样
  • yield将函数截成两个状态
  • Generator不会自己执行,而是返回一个遍历器对象
  • 遍历器对象通过.next()方法调用各个状态

Generator可用于消息传递

function *x() {
    let x = yield '我启动了!'
    let y = yield (x + 3)
    let z = yield (y * 3)
    return (x * 2)
}

let y = x()

console.log(y.next(1))  // {value: "我启动了!", done: false}
console.log(y.next(2))  // {value: 5, done: false}
console.log(y.next(100)) // {value: 300, done: false}
console.log(y.next(1000)) // {value: 4, done: true}

async、await就是Genarator的语法糖

通过Generator函数加自动执行器实现,于是不需要一直next()

function f() {
    return new Promise(resolve =>{
        resolve('hhh')
    })
}
async function doSomething1(){
    let x = await f()
    console.log(x)
}

doSomething1()

//hhh
  1. async 修饰符表示这个函数是异步函数
  2. await 是个运算符,阻塞后面代码
  3. await 如果等到的Promise对象就得到其resolve值
async function doSomething1(){
    let x = await 'hhh'
    return x
}

console.log(doSomething1())

doSomething1().then(res => {
    console.log(res)
})

//打印结果:
//Promise {<pending>}
//hhh
  1. async 返回一个Promise对象,async修饰的函数内部返回的值,会成为then中回调方法的参数
  2. await如果等到的不是Promise对象,就得到一个表达式的运算结果

参考:zhuanlan.zhihu.com/p/134691646