promise-async-await

  異步就是比較耗時的操做,CPU緩存的速度是最快的,而後是內存,而後是硬盤,因此從硬盤上讀取文件是很是慢的,js認爲從硬盤上讀取文件是一個異步操做;另一種是網絡請求,這種也是異步的;操做dom節點也是很是耗時的,但倒是同步操做,由於做爲異步來處理比較麻煩。node

  promise就是一個承諾,在js中就是承諾過段時間會返回一個結果,而這個過段時間就指的是異步操做。webpack

  promise本質上是一個有限狀態機,狀態機指的是根據特定的條件按照必定的順序進行轉換,並且過程不可逆。每一個promise實例都有三種狀態:pending、resolve、reject。在狀態機中,須要某些條件才能將本身的狀態觸發。git

  狀態只有兩種:從初始狀態到成功:pending->resolve;從初始狀態到失敗:pending->reject。promise實例狀態機狀態的變化會觸發promise原型上的then或catch方法的執行github

  DOM規範是運行在瀏覽器上的規範,好比navigator,只在dom上有,在node上沒有;而ECMAScript規範,不只在瀏覽器中可使用,也能夠在node.js中使用。web

如何構建一個promiseajax

  構建一個promise實例須要給promise構造函數傳入一個有兩個形參的函數,第一個形參運行後會讓promise實例處於resolve狀態,因此通常用resove表示成功狀態;第二個形參運行後會讓promise實例處於reject狀態,因此通常用reject表示失敗狀態。new出來的promise實例,有兩個方法(then,catch,then捕獲成功的操做,catch捕獲失敗的操做。),而且能夠鏈式調用。在使用的時候,要將then放在catch的上面,這是由於then裏的錯誤也能夠在catch中捕獲到,如代碼所示:json

let promiseInstance = new Promise((resolve,reject) =>{ setTimeOut(() => { resolve('this is resolve.') }) }) promiseInstance .then((value)=>{console.log(value)}).catch((err)=>{console.error(err)})

    promise是處理異步的,而網絡請求是異步最多見的場景,因此能夠用promise封裝一個網絡請求的方法,因此不少時候promise的實例是做爲函數的返回值是,調用函數後能夠對返回值的Promise對象進行相應的操做api

function ajaxPromise(){
  return new Promise((resolve,reject) => {
    let xhr = new XMLHttpRequest();
    xhr.open('get',queryUrl,true);
    xhr.send(null);
    xhr.onReadyStatechange = () => {
      if(xhr.readyState === 4){
        if(xhr.status === 200){
          resolve(xhr.responseText);
        }else{
          reject(xhr.responseText)
        }
      }
    }
  }) }

ajaxPromise('http://api.github.com/')
.then((value) => {
  console.log(value);
})
.catch((err) => {
  console.error(err)
})

then與catch的使用promise

  狀態機的狀態是不可逆的,因此執行了resolve方法,就算再執行reject方法,也不會有效果了。瀏覽器

promise的api

  promise實例上的方法

    promise.prototype.then()

    promise.prototype.catch()

  promise構造函數上的方法

    promise.all(Array) 返回一個promise,等待參數中全部的promise都處於resolve狀態後會觸發返回的promise實例的resolve狀態

    promise.race(Array) 返回一個promise,參數中第一個執行完成的狀態決定出發哪一個函數

    promise.resolve() 馬上返回一個resolve狀態的實例

    promise.reject() 馬上返回一個reject狀態的實例

let promise1 = new Promise((resolve,reject)=>{ setTimeout(resolve,1000,'success1') }) let promise2 = new Promise((resolve,reject)=>{ setTimeout(resolve,1000,'success12') }) let promise3 = new Promise((resolve,reject)=>{ setTimeout(resolve,1000,'success3') }) Promise.all([promise1, promise2, promise3]).then((value)=>{ console.log(value) }).catch((err)=>{ console.error(err) })

tips:setTimeOut的第三個參數,是第一個函數參數執行的時候,要傳入的參數

promise.then的執行時機

  promise.resolve是處理異步問題的,因此會先把同步的代碼執行完,再執行promise.resolve返回實例的then或catch的代碼

  而Promise構造函數是同步的,then方法是異步的。setTimeOut的執行時機是最晚的

promise並非處理異步最好的方法,好比回調金字塔的問題並無解決,只是看起來更清晰了。解決異步最好的方法是async

generator

  有點像一個函數內部有多個函數,是一個狀態機,yield生成

function* genFunc(){   yield 'hello';
  yield 'generator';
  yield '!'
  return 'end'//generator不建議使用return
}

 generator返回的不是返回值,也不是一個生成的內容,而是一個迭代器,迭代器是一個可遍歷的對象,迭代器有個next方法。經過for-of循環遍歷迭代器

連續運行的generator

function* genFunc(initValue){   let first = yield new Promise((resolve,reject)=>{     setTimeOut(resolve,1000,'1'+initValue)   })   let second = yield new Promise((resolve,reject)=>{     setTimeOut(resolve,1000,'2-'+first)   })   let third = yield new Promise((resolve,reject)=>{     setTimeOut(resolve,1000,'3-'+second)   })   let genHandler = genFunc(1)   genHandler.next().value.   then((value) => {     genHandler.next(value).value.     then((value) => {       then((value) => {         console.log(value);       })     })   }) } 

co庫與async函數

  import co from 'co'

  上述代碼中依然有回調金字塔,能夠用co庫解決

co(genFunc(1)).then((value) => {console.log(value)})//2-11

  async至關因而generator+promise+co,是es7的新語法,目前沒有瀏覽器實現,因此須要用webpack+babel編譯一下才能夠運行。

 

 

如何同步異步請求,即兩次請求,異步執行,如何在兩次請求都執行完成的狀況下執行後續程序

function request(content){ setTimeout(()=>{ document.body.append(content) },Math.floor(Math.random()*1000)) //時間控制爲不肯定
} request('hello') request('world') //如何在兩次request完成後執行代碼。可使用promise.all,只要兩個異步有一個完成就能夠,可使用promise.race
docuement.body.append('finished')

如何處理回調嵌套回調

//珠峯課堂是先去服務端拿取token,而後再去拿課程
fetch('https://ketang.zhufengpeixun.cn/token') .then(response => { response.json().then(tokenJson =>{ const token = tokenJson fetch('https:ketang.zhufengpeixun.cn/course') .then( response =>{ response.json().then(tokenJson =>{ } }) }) })

promise定義:用於異步計算,表明一個當前、將來或永遠不可用的值  

//promise中的代碼段被直接執行了
const promise = new Promise((resolve,reject){ document.body.append('hello') }) const a = () =>{ document.body.append('world') } a(); //執行結果是hello world
//用promise表示一個將來的值
function resolve_example(){ const promise = new Promise((resolve,reject)=>{ document.body.append('start.....'); setTimeout(()=>{//promise表明了一個將來值
        resolve('done') },2000) }) return promise; } const promise = resolve_example(); //獲得一個將來完成的值,此處data是異步返回的部分
promise.then(data => { document.body.append(data) })

 

promise有三種狀態,當被new出來的時候屬於pending狀態,使用resolve則是fulfill狀態,使用reject則是fail狀態

Executor是構造Promise的惟一參數,在promise構造的時候會被立刻執行

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息