47.async/await

113 阅读1分钟

async/await在我们的开发中出现还是很多的.是我们结局异步是十分好用的

基本使用

在函数前加上async 在异步任务前加await关键字,就可以使await后面的代码逐行执行 不受异步影响.

const getData = () =>
  new Promise((resolve) => setTimeout(() => resolve('data'), 1000));

// 这样的一个async函数 应该再1秒后打印data
async function test() {
  const data = await getData();
  console.log('data: ', data);
  const data2 = await getData();
  console.log('data2: ', data2);
  console.log('ok');
  return 'success';
}
test();
// data:  data
data2:  data
ok

我们可以看到我们的同步任务('ok')是在异步任务后执行的,所以证明我们使用async/await是成功的.

原理

async的执行原理 其实就是自动执行generator函数

function* testG() {
  // await被编译成了yield
  const data = yield getData();
  console.log('data: ', data);
  const data2 = yield getData();
  console.log('data2: ', data2);
  console.log('ok');
  return 'success';
}

function asyncToGenerator(generatorFunc) {
  return function () {
    const gen = generatorFunc.apply(this, arguments);

    return new Promise((resolve, reject) => {
      function step(key, arg) {
        let generatorResult;
        try {
          generatorResult = gen[key](arg);
        } catch (error) {
          return reject(error);
        }

        const { value, done } = generatorResult;

        if (done) {
          return resolve(value);
        } else {
          return Promise.resolve(value).then(
            function onResolve(val) {
              step('next', val);
            },
            function onReject(err) {
              step('throw', err);
            }
          );
        }
      }
      step('next');
    });
  };
}

const testGAsync = asyncToGenerator(testG);
testGAsync().then((result) => {
  console.log(result);  //data:  data
data2:  data
ok
});