溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

什么是promise

發(fā)布時間:2020-09-25 11:41:02 來源:億速云 閱讀:147 作者:小新 欄目:web開發(fā)

這篇文章給大家分享的是有關(guān)什么是promise的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考。一起跟隨小編過來看看吧。

promise是什么

官網(wǎng)解釋 promise 表示一個異步操作的最終結(jié)果。

翻譯  ==可以將promise理解為一個狀態(tài)機==,它存在三種不同的狀態(tài),并在某一時刻只能有一種狀態(tài)

pending 表示還在執(zhí)行resolved 執(zhí)行成功rejected 執(zhí)行失敗

一個promise是對一個異步操作的封裝,異步操作有等待完成、成功和失敗三種可能的結(jié)果,對應(yīng)了promise的三種狀態(tài)。

promise的狀態(tài)只能有pending轉(zhuǎn)換位resolved或者pending轉(zhuǎn)換為rejected,一旦狀態(tài)轉(zhuǎn)化完成就無法再改變。

假設(shè)我們用promise封了一個異步操作,那么當它被創(chuàng)建的時候就處于pending狀態(tài),當異步操作成功完成時,
我們將狀態(tài)轉(zhuǎn)換為resolved,如果執(zhí)行中出現(xiàn)錯誤,將狀態(tài)轉(zhuǎn)換為rejected。

var promise=new Promise(function(resolve,reject){
  // code
  if(){
    /*異步操作成功 */
    resolve(value)
  }else{
    reject(error)
  }
})

使用then方法獲取結(jié)果

var fs=require('fs')
function readFile_promise(path){
  return new Promise(function(resolve,reject){
    fs.readFile(path, 'utf-8',function(err,data){
      if(data){
        resolve(data)
      }else{
        reject(err)
      }
    })
  })
}

var result=readFile_promise('./1.txt')
result.then(function(value){
  //success
  console.log('success', value)
},function(error){
  //failure
  console.log('failure',error)
})
// 將一個異步函數(shù)封裝成promise,只要在回調(diào)函數(shù)中針對不同的返回結(jié)果調(diào)用resolve或者reject方法。

// resolve函數(shù)會在異步操作成功完成時被調(diào)用,并將異步操作的返回值作為參數(shù)傳遞到外部。
// reject是在異步操作出現(xiàn)異常時被調(diào)用,會將錯誤信息作為參數(shù)傳遞出去。

then方法的返回值

then方法總是返回一個新的promise對象,多次調(diào)用then方法,默認返回一個一個空的promise對象
使用return來來返回。

var promise=readFile_promise('./foo.txt')
promise.then(function(value){
  //success
  console.log('success', value) // foo
  return readFile_promise('./bar.txt')
},function(error){
  //failure
  console.log('failure',error)
}).then(function(value){
  console.log('then', value) // bar
})
promise的執(zhí)行
  • 雖然我們是通過then方法來獲取promise的結(jié)果,但是promise是當then方法調(diào)用之后才執(zhí)行嗎?
var promise=new Promise((resolve, reject)=>{
  console.log('begin')
  resolve()
})

setTimeout(()=>{
  promise.then(()=>{
    console.log('end')
  })
},5000)
// 開始begin 5s后end
// 運行順序是,當promise從被創(chuàng)建的那一刻起就開始執(zhí)行了,then方法只是提供了訪問promise狀態(tài)的接口,與promise的執(zhí)行無關(guān)。
promise 常用的api
  • resolved
  • rejected
  • all
  • race 方法接收一個promise數(shù)組作為參數(shù)并返回一個新的promise,數(shù)組中的promise會同時開始執(zhí)行,race返回的promise的狀態(tài)有數(shù)組中率先執(zhí)行完畢的promise的狀態(tài)決定
  • catch 執(zhí)行出錯可以使用throw關(guān)鍵字拋出錯誤,并使用catch方法進行捕獲
 // 如果有多個promise需要執(zhí)行,可以使用promise.all()
// 方法統(tǒng)一聲明,改方法可以將多個promise對象包裝成一個promise
// 該方法接收一個數(shù)組作為參數(shù),數(shù)據(jù)的元素如果不是promise對象,則回先調(diào)用resolve方法轉(zhuǎn)換。
//  如果中間有一個promise狀態(tài)是reject,那么轉(zhuǎn)換后的promise也會變成reject,并且將錯誤信息傳給catch方法
var promises=['foo.txt','bar.txt','baz.txt']
promises.map(function(path){
  // console.log(path)
  return readFile_promise(path)
})

Promise.all(promises).then(function(results){
  console.log(results) // [ 'foo.txt', 'bar.txt', 'baz.txt' ] 順序排列的
}).catch(function(err){
  // 
})
使用promise組織異步代碼
// 例子; 有三個文本文件需要順序讀取
var lists=['foo.txt','bar.txt','baz.txt']
var count=0;
readFile_promise('foo.txt').then(readCB).then(readCB).then(readCB);

function readCB(data){
  console.log(data) // foo bar baz
  if(++count>2){
    return
  }
  return readFile_promise(lists[count])
}

async/await

await關(guān)鍵字后面往往是一個promise,如果不是就隱式調(diào)用promise.resolve來轉(zhuǎn)換成一個promise。
await 等待后面的promise執(zhí)行完成再進行下一步操作。

var asyncReadFile=async function(){
  var result1=await readFile_promise('./foo.txt')
  console.log(result1.toString()) // foo
}
asyncReadFile()
async返回值

async函數(shù)總是會返回一個promise對象,如果return關(guān)鍵字后面不是一個promise,那么默認
調(diào)用promise。resolve方法進行轉(zhuǎn)換。

async function asyncFunc(){
  return 'hello Node'
}
asyncFunc().then(function(data){
  console.log(data) // hello Node
})
async函數(shù)的執(zhí)行過程
  1. 在async函數(shù)開始執(zhí)行的時候回自動生成一個promise對象。
  2. 當方法體開始執(zhí)行后,如果遇到return關(guān)鍵字或者throw關(guān)鍵字,執(zhí)行會立刻退出,

如果遇到await關(guān)鍵字則回暫停執(zhí)行 await后面的異步操作結(jié)束后會恢復(fù)執(zhí)行

  1. 執(zhí)行完畢,返回一個promise
async function asyncFunc(){
  console.log('begin')
  return 'hello Node'
}
asyncFunc().then(function(data){
  console.log(data) // hello Node
  console.log('end')
})
// begin 
// hello 
// end
await

await 操作符的結(jié)果是由其后面promise對象的操作結(jié)果來決定的,如果后面promise對象變?yōu)閞esolved,
await操作符發(fā)返回的值就是resolve的值;如果promise對象的狀態(tài)變成rejected,那么await也會拋出reject的值。

async function readFile(){
  var result=await readFile_promise('./foo.txt')
  console.log(result) // foo
}
readFile()

// 等價于
readFile_promise('foo.txt').then(function(data){
  console.log(data) // foo
})
await于并行

await會等待后面的promise完成后再采取下一步動作,這意味著當多個await操作時,程序會便成完全的
串行操作。

當異步操作之間不存在依賴關(guān)系時,可以使用promise.all來實現(xiàn)并行。

async function readFile(){
  const [result1, result2]=await Promise.all([
    readFile_promise('./foo.txt'),
    readFile_promise('./bar.txt')
  ])
  console.log(result1, result2) // foo bar
}
readFile()

// 等價于
function readFile(){
  return Promise.all([
    readFile_promise('./foo.txt'),
    readFile_promise('./baz.txt')
  ]).then((result)=>{
    console.log(result) // [ 'foo', 'baz' ]
  })
}
readFile()

await 總結(jié)

await關(guān)鍵字使用的一些關(guān)鍵點
  • await關(guān)鍵字必須位于async函數(shù)內(nèi)部
  • await關(guān)鍵字后面需要是一個promise對象(不是的話就調(diào)用了resolve轉(zhuǎn)換的)
  • await關(guān)鍵字的返回結(jié)果就是在其后面promise執(zhí)行的結(jié)果,可能是resolved或者rejected的值
  • 不能在普通箭頭函數(shù)中使用await關(guān)鍵字,需要在箭頭函數(shù)前面加上async關(guān)鍵字。
  • await用來串行地執(zhí)行異步操作,想實現(xiàn)并行使用promise.all

async函數(shù) 的缺點

假設(shè)我們有很多層的方法調(diào)用,最底層的異步操作被封裝成了async方法,那么該函數(shù)的所有上層方法可能都要變成async方法。

感謝各位的閱讀!關(guān)于什么是promise就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI