Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

今日头条: 对async/await的理解以及内部原理(一面) #6

Open
acodercc opened this issue Apr 30, 2019 · 2 comments
Open

Comments

@acodercc
Copy link
Member

acodercc commented Apr 30, 2019

To:
focus7eleven

面试公司:
今日头条

面试环节:
一面

问题:
谈谈对async/await的理解,以及内部原理

@acodercc acodercc changed the title To 龙茶: 对Async、Await的理解以及内部原理(今日头条) To 龙茶: 对async/await的理解以及内部原理(今日头条) Apr 30, 2019
@focus7eleven focus7eleven self-assigned this Apr 30, 2019
@acodercc acodercc changed the title To 龙茶: 对async/await的理解以及内部原理(今日头条) To focus7eleven: 对async/await的理解以及内部原理(今日头条) Apr 30, 2019
@focus7eleven
Copy link

focus7eleven commented Apr 30, 2019

async / await 是一种更方便地完成异步调用的语法

基本含义

async 使得后面的 function 始终返回一个 promise,无论 function 本身返回的是否是 promise。

await 必须在 async 函数内部使用,只有等到 await 后面的部分执行完成后,函数才会继续往下执行。
举例来说:

async function f() {

  const promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("done!"), 1000)
  })

  const result = await promise; // wait till the promise resolves (*)

  alert(result)

  alert('end of function')
}

f();

执行结果:

done
end of function

await 会把后面的 promise 放到 microtask queue 中,所以当 await 和 setTimeout 放到一起时,会先执行 await 的部分,再执行 setTimeout 的部分(setTimeout 会进入 macrotask,优先级低于 microtask)。比如:

async function f() {
  return 1;
}

(async () => {
    setTimeout(() => alert('setTimeout is done'), 0);

    await f();
    alert('await is done'); 
})();

执行结果:

await is done
setTimeout is done

基本原理

async / await 本质上是 generator 的语法糖,与 generator 相比,多了以下几个特性:

  • 内置执行器,无需手动执行 next() 方法
  • await 后面的函数可以是 promise 对象也可以是普通 function,而 yield 关键字后面必须得是 thunk 函数或 promise 对象
async function fn(args) {
  // ...
}

等同于:

function fn(args) {
  return spawn(function* () {
    // ...
  });
}

而 spawn 函数就是所谓的自动执行器了

function spawn(genF) {
  return new Promise(function(resolve, reject) {
    const gen = genF();
    function step(nextF) {
      let next;
      try {
        next = nextF();
      } catch(e) {
        return reject(e);
      }
      if(next.done) {
        return resolve(next.value);
      }
      Promise.resolve(next.value).then(function(v) {
        step(function() { return gen.next(v); });
      }, function(e) {
        step(function() { return gen.throw(e); });
      });
    }
    step(function() { return gen.next(undefined); });
  });
}

@acodercc acodercc modified the milestones: 待回答, 已回答 Apr 30, 2019
@zsxsoft
Copy link

zsxsoft commented Apr 30, 2019

都好多年了诶这个问题
当年写了篇文章,虽然现在看没啥重点 https://blog.zsxsoft.com/post/21

@acodercc acodercc changed the title To focus7eleven: 对async/await的理解以及内部原理(今日头条) 今日头条: 对async/await的理解以及内部原理(一面) May 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants