super-fool / blog

珍藏经典, 分享思想, 共同进步.加油
3 stars 0 forks source link

async / await #71

Open super-fool opened 3 years ago

super-fool commented 3 years ago
function exc() {
  new Promise((res) => {
    console.log(1);
    res();
    console.log(2);
  })
    .then((res) => {
      console.log(3);
    })
    .catch((err) => {
      console.log("err");
    });
}

exc();

console.log(4);

执行顺序?

super-fool commented 3 years ago

exc函数是一个同步函数,那么先执行,将该函数放入同步栈中,所以肯定先打印 1,遇到了resolve,那么会将链式的第一个then放入异步队列中,然后继续执行打印2. 在打印2后发现exc函数内部的代码已全部执行完毕,然后推出同步栈,执行最外部的代码,打印4. 执行完发现所有的同步代码都已经执行完毕,那么从异步队列中pop异步代码进行执行。

所以最后的打印顺序为: 1, 2, 4, 3

super-fool commented 3 years ago

接下来,我们改变一下:

function exec() {
  new Promise((res) => {
    console.log(1);
    res();
    console.log(2);
  })
    .then((res) => {
      console.log(3);
    })
    .then((res) => {
      console.log(5);
    })
    .catch((err) => {
      console.log("err");
    });
}

// exec();
await (exec());

console.log(4);

这样执行会是怎样的执行方式呢?

这里要注意:await只能在async函数中去调用才有效,如果不将exec()用括号包裹着,便会报语法错误: SyntaxError: await is only valid in async function

现在随着现代前端代码逐渐迁移到了 ES Module(默认是严格模式),标准委员会也在计划扩大 await的使用场景,所以有了 !-top-level await 提案 。在这个提案里,只要是在 Module 环境下,我们是可以直接写 await的, 报错也做了相应的改变:Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules

super-fool commented 3 years ago

第一,我们在之前的代码中又添加了一个then, 第二,我们将exec函数用await进行执行。

那么我们首先要了解 awaitawait是一个generator().next(), 或者说是一个Promise.resolve()

所以返回: 1, 2, 3, 4, 5

super-fool commented 3 years ago

异步任务: 多个请求时同时请求的, 即并行的触发的. but! 每个请求的回调函数是注册到任务队列中的, 以FIFO的规则进行调用.

实现一个任务队列:

// 队列的方法有: enqueue, dequeue, front, isEmpty, size

let Queue = ~function() {
const items = new WeakMap();
class Queue {
constructor() {
  items.set(this, []);
}

getQueue() {
  return items.get(this);
}

enqueue(item) {
  this.getQueue().push(item)
}

dequeue() {
  this.getQueue().shift();
}

front() {
  return this.getQueue()[0]
}

isEmpty() {
  this.getQueue().length = 0;
}
return Queue;
}
}()