成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

半理解系列--Promise的進化史

Eminjannn / 3444人閱讀

摘要:異步編程一般用來調(diào)取接口拉數(shù)據(jù)。通過我描述的篇幅,就知道異步編程比同步編程麻煩許多。遠古時期,異步編程是通過回調(diào)函數(shù)來解決的。

半理解系列--Promise的進化史

學(xué)過js的都知道,程序有同步編程和異步編程之分,同步就好比流水線,一步一個腳印,做完上個任務(wù)才做下一個,異步編程好比客服,客服接了一個電話,收到了一個任務(wù),然后把任務(wù)交給另外的人來處理,同時,繼續(xù)接聽下一個電話,等到另外的人處理完任務(wù)了,再通知客服,客服再反饋給第一個打電話的人。異步編程一般用來調(diào)取接口拉數(shù)據(jù)。

通過我描述的篇幅,就知道異步編程比同步編程麻煩許多。遠古時期,異步編程是通過回調(diào)函數(shù)來解決的。但是回調(diào)函數(shù)會有回調(diào)地獄的問題,回調(diào)的多了,維護人員看起來頭都大了,好比:taskC需要等待taskB做完(taskC才執(zhí)行),taskB又需要等待taskA做完(taskB才執(zhí)行)

function taskA (cb) {
  //..do task A
  cb()
}
function taskB(cb){
  //..do task B
  cb()
}
function taskC(cb){
  //..do task C
  cb()
}
taskA(function(){
  taskB(function(){
    taskC()
  })
})
...以此類推,不斷循環(huán)嵌套,最終陷入地獄

而Promise就把這一系列的回調(diào),通過鏈?zhǔn)秸{(diào)用的方式連接起來,看起來清爽多了。同樣是上面的代碼,Promise可以這么寫(偽代碼)

new Promise().then(taskA).then(taskB).then(taskC)
promise的使用
const promise = new Promise((resolve,reject)=>{
  if (/*do something done*/){
    resolve() // 可在此傳參數(shù)
  } else {
    // do something fail
    reject() // 可在此傳參數(shù)
  }
})
promise.then(()=>{
  //do something
}).catch(e => { throw e})

上面的resolve,可以當(dāng)作task函數(shù)的cb回調(diào)函數(shù),當(dāng)resolve()執(zhí)行的時候,then方法中的回調(diào)會被執(zhí)行,如果是reject執(zhí)行,錯誤會被catch捕捉。

Promise的靜態(tài)方法

上面說的thencatch都是Promise的原型方法,即Promise.prototype.then/catch
Promise本身有兩個靜態(tài)方法,其作用類似 new Promise()

Promise.resolve()

const promise1 = Promise.resolve()

等價于

const promise2 = new Promise((reslove)=>{
  reslove()
})

使用該方法調(diào)用then方法
Promise.reject()

const promise1 = Promise.reject()

等價于

const promise2 = new Promise((resolve,reject)=>{
  reject()
})

使用該方法會被catch捕捉

Promise的鏈?zhǔn)秸{(diào)用

Promise的實例對象的then方法是可以重復(fù)調(diào)用的,then方法返回的是一個promise實例對象,所以可以重復(fù)調(diào)用then方法,并且(敲黑板),上一個then方法的返回值,會作為下一個then方法的參數(shù)傳遞

舉個栗子:

const promise = Promise.resolve("start")

promise.then((params)=>{
  console.log(params) // start
  return "aa"
}).then((params) => {
  console.log(params) // aa
  return "bb"
}).then((params)=>{
  console.log(params) // bb
  return "cc"
})

// 最后會返回一個狀態(tài)是resolve(cc)的promise對象:Promise?{: "cc"}

深入一下(又不會懷孕)

function badAsyncCall() {
  var promise = Promise.resolve();
  promise.then(function() {
      // 任意處理
      return "newVar";
  });
  return promise;
}
// 修改一下
function goodAsyncCall() {
  var promise = Promise.resolve();
  return promise.then(function() {
      // 任意處理
      return "newWar";
  });
}

以上兩個寫法是不是很相似,唯一不同的就是return的處理。但調(diào)用,badAsynccall會出錯,而anAsyncCall能正確執(zhí)行,比如:

badAsyncCall().then(params => { console.log("bad--",params)}) // bad-- undefined
goodAsyncCall().then(params => { console.log("good--",params)}) // good-- newWar

分析:第一種,錯誤寫法,首先在 promise.then 中產(chǎn)生的異常不會被外部捕獲,此外,也不能得到 then 的返回值,即使其有返回值。
原因:由于每次 promise.then 調(diào)用都會返回一個新創(chuàng)建的promise對象,第一種返回的promise,相當(dāng)于沒有調(diào)用過函數(shù)內(nèi)部的then方法,是一個全新的promise實例對象
結(jié)論: 統(tǒng)一使用promise鏈?zhǔn)秸{(diào)用,如:promise.then(taskA).then(taskB)

### async&await和promise的前世緣緣

promise說白了還是用回調(diào)的方式來解決異步問題,跟真正同步還是有差距的。
異步編程的最高境界,就是根本不用關(guān)心它是不是異步!(來之ruanyifeng老師的話)

所以,async&await方案出現(xiàn)了

用法:

function readFile(fileName) {
  return new Promise((resolve,reject)=>{
    fs.readFile(fileName, function(error, data) {
      if (error) return reject(error);
      resolve(data); // 向thenc傳送異步讀取文件的數(shù)據(jù)
    });
  })
}

// 調(diào)用

readFile(fileName).then(function(data){
  console.log("prmoise read files data --", data)
})


// 等價于

async function asyncFn(fileName){
  const data = await readFile(fileName)
  console.log("await data --", data)
  return data
}

asyncFn(fileName) 

寫法是不是簡潔了許多!
其實async就是一個Promise的語法糖,它的返回值是一個promise對象,因此可以用then方法做鏈?zhǔn)秸{(diào)用(但參數(shù)就是async函數(shù)中的返回值,如上文的data?。。?/p>

async函數(shù)中還可以不使用promise,比如:

async function asyncFn(){
  const data = await setTimeout(function(){
    console.log("setTimeout") 
    return "data"
  },1000)
  console.log("data",data) // Timeout {} 對象
}
console.log("async",asyncFn()) // Promise {  }

但這兩者,其實經(jīng)常混用,常見的就是readFile函數(shù)的做法啦

看懂以上的,才大家出一道題看看能不能懂;

async function asynFn(){ 
  await Promise.resolve("aaa")
  const data = {
    b:"bb",
    c:function(){ return this.b }
  }
  return data  //return 作為參數(shù)傳遞給then then的chain鏈也是通過return參數(shù)來不斷傳遞給后面的then
}
var cball = asynFn()
cball.then(function(data){
  console.log("data:",data)
})

還有一種異步編程的語法糖: * & yield
跟async基本一樣,不在本文討論的重點。有興趣自行g(shù)oogle啦

參考資料:
async 函數(shù)的含義和用法
Promise 對象

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/107430.html

相關(guān)文章

  • JavaScript 異步化史

    摘要:簽訂協(xié)議的兩方分別是異步接口和。在異步函數(shù)中,使用異常捕獲的方案,代替了的異常捕獲的方案。需要注意的是,在異步函數(shù)中使異步函數(shù)用時要使用,不然異步函會被同步執(zhí)行。 同步與異步 通常,代碼是由上往下依次執(zhí)行的。如果有多個任務(wù),就必需排隊,前一個任務(wù)完成,后一個任務(wù)才會執(zhí)行。這種執(zhí)行模式稱之為: 同步(synchronous) 。新手容易把計算機用語中的同步,和日常用語中的同步弄混淆。如,...

    luzhuqun 評論0 收藏0
  • 前端文檔收集

    摘要:系列種優(yōu)化頁面加載速度的方法隨筆分類中個最重要的技術(shù)點常用整理網(wǎng)頁性能管理詳解離線緩存簡介系列編寫高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪問性能優(yōu)化方案實現(xiàn)的大排序算法一怪對象常用方法函數(shù)收集數(shù)組的操作面向?qū)ο蠛驮屠^承中關(guān)鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁面加載速度的方法 隨筆分類 - HTML5 HTML5中40個最重要的技術(shù)點 常用meta整理 網(wǎng)頁性能管理詳解 HTML5 ...

    jsbintask 評論0 收藏0
  • 前端文檔收集

    摘要:系列種優(yōu)化頁面加載速度的方法隨筆分類中個最重要的技術(shù)點常用整理網(wǎng)頁性能管理詳解離線緩存簡介系列編寫高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪問性能優(yōu)化方案實現(xiàn)的大排序算法一怪對象常用方法函數(shù)收集數(shù)組的操作面向?qū)ο蠛驮屠^承中關(guān)鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁面加載速度的方法 隨筆分類 - HTML5 HTML5中40個最重要的技術(shù)點 常用meta整理 網(wǎng)頁性能管理詳解 HTML5 ...

    muddyway 評論0 收藏0
  • 人工智能革命:從ANI到AGI道路

    摘要:截至目前,人類大腦是已知宇宙中最復(fù)雜的物體。但是天河二號也是一個龐大的家伙,它占地平方米,使用兆瓦的電力大腦只需瓦,耗資億美元建造。建議,通過查看可以以,美元購買多少來考慮計算機的狀態(tài)。 showImg(http://upload-images.jianshu.io/upload_images/13825820-c158f685feaf8ae6.jpg?imageMogr2/auto-...

    pkwenda 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<