Callbacks, Promises and Async/Await

155 阅读2分钟

为了简要说明Promise,常见函数设置为胖箭头函数。

function() {}     function(a) {}      function(a,b) {}
替代为
() => {}          a => {}            (a,b) => {}

举例说明一个函数,随机打印一个字符串

function printString(string){
  setTimeout(
    () => {
      console.log(string)
    }, 
    Math.floor(Math.random() * 100) + 1
  )
}
function printAll(){
  printString("A")
  printString("B")
  printString("C")
}
printAll()

顺序随机,如果想固定,则用Callbacks

1. CallBacks

function printString(string, callback){
  setTimeout(
    () => {
      console.log(string)
      callback()  //callback is a reference
    }, 
    Math.floor(Math.random() * 100) + 1
  )
}
function printAll(){
  printString("A", () => {
    printString("B", () => {
      printString("C", () => {})
    })
  })
}
printAll()

太多Callback,号称callbackhell

2. Promises

function printString(string){
  return new Promise((resolve, reject) => {
    setTimeout(
      () => {
       console.log(string)
       resolve()
      }, 
     Math.floor(Math.random() * 100) + 1
    )
  })
}

把整个函数,包闭在promise内,成功后resolve,错误则reject;返回一个promise object

function printAll(){
  printString("A") 
  .then(() => {  //consume promise
    return printString("B")  //return promise;可以去掉return
  })
  .then(() => {  //consume promise
    return printString("C")  
  })
}
printAll()

使用胖箭头简化下

function printAll(){
  printString("A")
  .then(() => printString("B"))
  .then(() => printString("C"))
}
printAll()

function getPromise () { return new Promise((resolve) => { setTimeout(resolve, 2000) }) }

第二个例子

function getPromise () {
  return new Promise((resolve) => {
    setTimeout(resolve, 2000)
  })
}

function logA () {
  console.log('A')
}

function logB () {
  console.log('B')
}

function logCAndThrow () {
  console.log('C')

  throw new Error()
}

function catchError () {
  console.log('Error!')
}

getPromise()
  .then(logA) // A
  .then(logB) // B
  .then(logCAndThrow) // C
  .catch(catchError) // Error!

3. Await Async

Await就是promise的语法糖syntactic sugar

function printAll(){
  printString("A")
  .then(() => printString("B"))
  .then(() => printString("C"))
}
printAll()
async function printAll(){  //must use async before await to enable await...within the function
  await printString("A")    //no need to use then...
  await printString("B")
  await printString("C")
}
printAll()

async必须在await前,因此await必要用在函数内,不能用在全局global 如果用在global则需要如此IIFEE:

(async () => { 
  await myDate();
})();

继续研究。。。上面的await只是关于顺序问题,没有涉及到数据的传递和返回,如果需要传递和返回怎么办呢?

a.callback

function addString(previous, current, callback){
  setTimeout(
    () => {
      callback((previous + ' ' + current))
    }, 
    Math.floor(Math.random() * 100) + 1
  )
}
function addAll(){
  addString('', 'A', result => {
    addString(result, 'B', result => {
      addString(result, 'C', result => {
       console.log(result) // Prints out " A B C"
      })
    })
  })
}
addAll()

b.promise

function addString(previous, current){
  return new Promise((resolve, reject) => {
    setTimeout(
      () => {
        resolve(previous + ' ' + current)
      }, 
      Math.floor(Math.random() * 100) + 1
    )
  })
}


function addAll(){  
  addString('', 'A')
  .then(result => {
    return addString(result, 'B')  //must return,because we need the resolved value!!!
  })
  .then(result => {
    return addString(result, 'C')
  })
  .then(result => {
    console.log(result) // Prints out " A B C"
  })
}
addAll()

用胖箭头如下


function addAll(){  
  addString('', 'A')
  .then(result => addString(result, 'B'))
  .then(result => addString(result, 'C'))
  .then(result => {
    console.log(result) // Prints out " A B C"
  })
}
addAll()

c.await

async function addAll(){
  let toPrint = ''
  toPrint = await addString(toPrint, 'A')  //相当于promise then
  toPrint = await addString(toPrint, 'B')
  toPrint = await addString(toPrint, 'C')
  console.log(toPrint) // Prints out " A B C"
}
addAll()