preface

Now ECMAScript6 asynchronous programming, we all like to handle with async/await solutions, and the code looks great to write. But the underlying implementation principle is relatively few people understand, and then the interview is often asked recently, write an article to record.

What is async/await?

Our previous asynchronous programming schemes had callback functions, Promise objects, Generator functions, and now E7’s async/await. We can learn from its implementation principle that async/await is the syntactic sugar of Generator function, which can be understood as async/await = Generator function + automatic executor.

Implementation principle of async/await

// Generator function + automatic executor
function spawn (genF) {
  return new Promise(function(resolve, reject) {
    var gen = genF()
    
    function step (nextF) {
      var next
      try {
        next = nextF()
      } catch (error) {
        return reject(error)
      }

      if (next.done) return resolve(next.value)

      Promise.resolve(next.value).then(
        function(value) {
          step(function() {
            return gen.next(value)
          })
        }, 
        function(error) {
          step(function() {
            return gen.throw(error)
          })
        })
    }

    step(function() {
      return gen.next()
    })
  })
}
Copy the code

Generator functions implement async/await use cases

// An asynchronous function example
function wait(time) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve(`wait time: ${time}`)
    }, time)
  })
}

/* generator test start */
function * genF(time = 1000) {
  let res = yield wait(time)
  console.log(res)
}
function asyncByGen() {
  if(typeof arguments[0]! = ='function') throw('first argument must be a function')
  var fn = arguments[0]
  var args = Array.prototype.slice.call(arguments.1)
  return spawn(fn.bind(null, args))
}
// use 
asyncByGen(genF, 1200) // wait time: 1200
/* generator test end */

/* async test start */
async function asyncF(time = 1000) {
  let res = await wait(time)
  console.log(res)
}
// use 
asyncF(1200) // wait time: 1200
/* async test end */
Copy the code

The last

This article is through learning Ruan Dashen asynchronous programming series of articles, and then code to achieve a time, than before simply read the article without code really want to harvest more. Make a little progress every day