欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript基礎(chǔ)教程之如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的promise

 更新時(shí)間:2018年09月11日 09:24:58   作者:wclimb  
看了些promise的介紹,還是感覺(jué)不夠深入,所以下面這篇文章主要給大家介紹了關(guān)于JavaScript基礎(chǔ)教程之如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的promise的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

我們?cè)陂_(kāi)發(fā)過(guò)程中大多會(huì)用到promise,想必大家對(duì)promise的使用都很熟練了,今天我們就來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的promise,實(shí)現(xiàn)的效果如有出入還往指正。

Promise/A+規(guī)范:

  • 首先重新閱讀了下A+的規(guī)范:
  • promise代表了一個(gè)異步操作的最終結(jié)果,主要是通過(guò)then方法來(lái)注冊(cè)成功以及失敗的情況,
  • Promise/A+歷史上說(shuō)是實(shí)現(xiàn)了Promise/A的行為并且考慮了一些不足之處,他并不關(guān)心如何創(chuàng)建,完成,拒絕Promise,只考慮提供一個(gè)可協(xié)作的then方法。

術(shù)語(yǔ):

  • promise是一個(gè)擁有符合上面的特征的then方法的對(duì)象或者方法。
  • thenable是定義了then方法的對(duì)象或者方法
  • value是任何合法的js的值(包括undefined,thenable或者promise)
  • exception是一個(gè)被throw申明拋出的值
  • reason是一個(gè)指明了為什么promise被拒絕

整體結(jié)構(gòu)

我們先來(lái)梳理一下整體的結(jié)果,以便后續(xù)好操作

class MyPromise {
 constructor(fn){
 
 }
 resolve(){

 }
 then(){

 }
 reject(){

 }
 catch(){

 }
}

Promise理論知識(shí)

摘抄至 http://es6.ruanyifeng.com/#docs/promise#Promise-all

Promise對(duì)象有以下兩個(gè)特點(diǎn)。

(1)對(duì)象的狀態(tài)不受外界影響。Promise對(duì)象代表一個(gè)異步操作,有三種狀態(tài):pending(進(jìn)行中)、fulfilled(已成功)和rejected(已失?。?。只有異步操作的結(jié)果,可以決定當(dāng)前是哪一種狀態(tài),任何其他操作都無(wú)法改變這個(gè)狀態(tài)。這也是Promise這個(gè)名字的由來(lái),它的英語(yǔ)意思就是“承諾”,表示其他手段無(wú)法改變。

(2)一旦狀態(tài)改變,就不會(huì)再變,任何時(shí)候都可以得到這個(gè)結(jié)果。Promise對(duì)象的狀態(tài)改變,只有兩種可能:從pending變?yōu)閒ulfilled和從pending變?yōu)閞ejected。只要這兩種情況發(fā)生,狀態(tài)就凝固了,不會(huì)再變了,會(huì)一直保持這個(gè)結(jié)果,這時(shí)就稱(chēng)為 resolved(已定型)。如果改變已經(jīng)發(fā)生了,你再對(duì)Promise對(duì)象添加回調(diào)函數(shù),也會(huì)立即得到這個(gè)結(jié)果。這與事件(Event)完全不同,事件的特點(diǎn)是,如果你錯(cuò)過(guò)了它,再去監(jiān)聽(tīng),是得不到結(jié)果的。

總結(jié)一下就是promise有三種狀態(tài):pending(進(jìn)行中)、fulfilled(已成功)和rejected(已失敗),還有就是狀態(tài)的改變只能是pending -> fulfilled 或者 pending -> rejected,這些很重要

實(shí)現(xiàn)構(gòu)造函數(shù)

現(xiàn)在我們開(kāi)始實(shí)現(xiàn)構(gòu)造函數(shù)

class MyPromise {
 constructor(fn){
 if(typeof fn !== 'function') {
  throw new TypeError(`MyPromise fn ${fn} is not a function`)
 }
 this.state = 'pending';
 this.value = void 0;
 fn(this.resolve.bind(this),this.reject.bind(this))
 }
 ...
}

構(gòu)造函數(shù)接收一個(gè)參數(shù)fn,且這個(gè)參數(shù)必須是一個(gè)函數(shù),因?yàn)槲覀円话氵@樣使用new Promise((resolve,reject)=>{});
然后初始化一下promise的狀態(tài),默認(rèn)開(kāi)始為pending,初始化value的值。

fn接收兩個(gè)參數(shù),resolve、reject

resolve

class MyPromise {
 constructor(fn){
 if(typeof fn !== 'function') {
  throw new TypeError(`MyPromise fn ${fn} is not a function`)
 }
 this.state = 'pending';
 this.value = void 0;
 fn(this.resolve.bind(this),this.reject.bind(this))
 }
 resolve(value){
 if(this.state !== 'pending') return;
 this.state = 'fulfilled';
 this.value = value
 }
 ...
}

當(dāng)resolve執(zhí)行,接收到一個(gè)值之后;狀態(tài)就由 pending -> fulfilled;當(dāng)前的值為接收的值

reject

class MyPromise {
 constructor(fn){
 if(typeof fn !== 'function') {
  throw new TypeError(`MyPromise fn ${fn} is not a function`)
 }
 this.state = 'pending';
 this.value = void 0;
 fn(this.resolve.bind(this),this.reject.bind(this))
 }
 resolve(value){
 if(this.state !== 'pending') return;
 this.state = 'fulfilled';
 this.value = value
 }
 reject(reason){
 if(this.state !== 'pending') return;
 this.state = 'rejected';
 this.value = reason
 }
}

當(dāng)reject執(zhí)行,接收到一個(gè)值之后;狀態(tài)就由 pending -> rejected;當(dāng)前的值為接收的值

then

class MyPromise {
 constructor(fn){
 if(typeof fn !== 'function') {
  throw new TypeError(`MyPromise fn ${fn} is not a function`)
 }
 this.state = 'pending';
 this.value = void 0;
 fn(this.resolve.bind(this),this.reject.bind(this))
 }
 resolve(value){
 if(this.state !== 'pending') return;
 this.state = 'fulfilled';
 this.value = value
 }
 reject(reason){
 if(this.state !== 'pending') return;
 this.state = 'rejected';
 this.value = reason
 }
 then(fulfilled,rejected){
 if (typeof fulfilled !== 'function' && typeof rejected !== 'function' ) {
  return this;
 }
 if (typeof fulfilled !== 'function' && this.state === 'fulfilled' ||
  typeof rejected !== 'function' && this.state === 'rejected') {
  return this;
 }
 return new MyPromise((resolve,reject)=>{
  if(fulfilled && typeof fulfilled === 'function' && this.state === 'fulfilled'){
  let result = fulfilled(this.value);
  if(result && typeof result.then === 'function'){
   return result.then(resolve,reject)
  }else{
   resolve(result)
  }
  }
  if(rejected && typeof rejected === 'function' && this.state === 'rejected'){
  let result = rejected(this.value);
  if(result && typeof result.then === 'function'){
   return result.then(resolve,reject)
  }else{
   resolve(result)
  }
  }
 })
 }
}

then的實(shí)現(xiàn)比較關(guān)鍵,首先有兩個(gè)判斷,第一個(gè)判斷傳的兩個(gè)參數(shù)是否都是函數(shù),如果部不是return this執(zhí)行下一步操作。
第二個(gè)判斷的作用是,比如,現(xiàn)在狀態(tài)從pending -> rejected;但是中間代碼中有許多個(gè).then的操作,我們需要跳過(guò)這些操作執(zhí)行.catch的代碼。如下面的代碼,執(zhí)行結(jié)果只會(huì)打印1

new Promise((resolve,reject)=>{
 reject(1)
}).then(()=>{
 console.log(2)
}).then(()=>{
 console.log(3)
}).catch((e)=>{
 console.log(e)
})

我們繼續(xù),接下來(lái)看到的是返回了一個(gè)新的promise,真正then的實(shí)現(xiàn)的確都是返回一個(gè)promise實(shí)例。這里不多說(shuō)

下面有兩個(gè)判斷,作用是判斷是rejected還是fulfilled,首先看fulfilled,如果是fulfilled的話,首先執(zhí)行fulfilled函數(shù),并把當(dāng)前的value值傳過(guò)去,也就是下面這步操作,res就是傳過(guò)去的value值,并執(zhí)行了(res)=>{console.log(res)}這段代碼;執(zhí)行完成之后我們得到了result;也就是2這個(gè)結(jié)果,下面就是判斷當(dāng)前結(jié)果是否是一個(gè)promise實(shí)例了,也就是下面注釋了的情況,現(xiàn)在我們直接執(zhí)行resolve(result);

new Promise((resolve,reject)=>{
 resolve(1)
}).then((res)=>{
 console.log(res)
 return 2
 //return new Promise(resolve=>{})
})

剩下的就不多說(shuō)了,可以debugger看看執(zhí)行結(jié)果

catch

class MyPromise {
 ...
 catch(rejected){
  return this.then(null,rejected)
 }
}

完整代碼

class MyPromise {
 constructor(fn){
  if(typeof fn !== 'function') {
   throw new TypeError(`MyPromise fn ${fn} is not a function`)
  }
  this.state = 'pending';
  this.value = void 0;
  fn(this.resolve.bind(this),this.reject.bind(this))
 }
 resolve(value){
  if(this.state !== 'pending') return;
  this.state = 'fulfilled';
  this.value = value
 }
 reject(reason){
  if(this.state !== 'pending') return;
  this.state = 'rejected';
  this.value = reason
 }
 then(fulfilled,rejected){
  if (typeof fulfilled !== 'function' && typeof rejected !== 'function' ) {
   return this;
  }
  if (typeof fulfilled !== 'function' && this.state === 'fulfilled' ||
   typeof rejected !== 'function' && this.state === 'rejected') {
   return this;
  }
  return new MyPromise((resolve,reject)=>{
   if(fulfilled && typeof fulfilled === 'function' && this.state === 'fulfilled'){
    let result = fulfilled(this.value);
    if(result && typeof result.then === 'function'){
     return result.then(resolve,reject)
    }else{
     resolve(result)
    }
   }
   if(rejected && typeof rejected === 'function' && this.state === 'rejected'){
    let result = rejected(this.value);
    if(result && typeof result.then === 'function'){
     return result.then(resolve,reject)
    }else{
     resolve(result)
    }
   }
  })
 }
 catch(rejected){
  return this.then(null,rejected)
 }
}

測(cè)試

new MyPromise((resolve,reject)=>{
 console.log(1);
 //reject(2)
 resolve(2)
 console.log(3)
 setTimeout(()=>{console.log(4)},0)
}).then(res=>{
 console.log(res)
 return new MyPromise((resolve,reject)=>{
 resolve(5)
 }).then(res=>{
 return res
 })
}).then(res=>{
 console.log(res)
}).catch(e=>{
 console.log('e',e)
})

執(zhí)行結(jié)果:

> 1
> 3
> 2
> 5
> 4

原生promise

new Promise((resolve,reject)=>{
 console.log(1);
 //reject(2)
 resolve(2)
 console.log(3)
 setTimeout(()=>{console.log(4)},0)
}).then(res=>{
 console.log(res)
 return new Promise((resolve,reject)=>{
 resolve(5)
 }).then(res=>{
 return res
 })
}).then(res=>{
 console.log(res)
}).catch(e=>{
 console.log('e',e)
})

執(zhí)行結(jié)果:

> 1
> 3
> 2
> 5
> 4

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • JavaScript類(lèi)的繼承操作實(shí)例總結(jié)

    JavaScript類(lèi)的繼承操作實(shí)例總結(jié)

    這篇文章主要介紹了JavaScript類(lèi)的繼承操作,結(jié)合實(shí)例形式總結(jié)分析了JavaScript面向?qū)ο蟪绦蛟O(shè)計(jì)中類(lèi)的繼承常見(jiàn)實(shí)現(xiàn)方式與操作技巧,需要的朋友可以參考下
    2018-12-12
  • js圖片模糊切換顯示特效的方法

    js圖片模糊切換顯示特效的方法

    這篇文章主要介紹了js圖片模糊切換顯示特效的方法,涉及js操作圖片特效的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • js事件機(jī)制----捕獲與冒泡機(jī)制實(shí)例分析

    js事件機(jī)制----捕獲與冒泡機(jī)制實(shí)例分析

    這篇文章主要介紹了js事件機(jī)制----捕獲與冒泡機(jī)制,結(jié)合實(shí)例形式分析了js事件機(jī)制中捕獲與冒泡機(jī)制相關(guān)原理、操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2020-05-05
  • javascript substr和substring用法比較

    javascript substr和substring用法比較

    在js中substring和substr都是用來(lái)截取字符串的,那么substring和substr之間的具體區(qū)別在哪里,有沒(méi)有區(qū)別呢,下面我來(lái)給各位詳細(xì)引用一些實(shí)例來(lái)介紹這些問(wèn)題
    2009-06-06
  • 常常會(huì)用到的截取字符串substr()、substring()、slice()方法詳解

    常常會(huì)用到的截取字符串substr()、substring()、slice()方法詳解

    javascript中給我們提供三個(gè)截取字符串的方法,分別是:slice(),substring()和substr()。下面我們對(duì)這三個(gè)函數(shù)進(jìn)行詳細(xì)說(shuō)明和比較,需要的朋友可以參考下
    2015-12-12
  • 用js腳本控制asp.net下treeview的NodeCheck的實(shí)現(xiàn)代碼

    用js腳本控制asp.net下treeview的NodeCheck的實(shí)現(xiàn)代碼

    根據(jù)TreeView2.js修改后的TreeView父節(jié)點(diǎn)與子節(jié)點(diǎn)的CheckBox聯(lián)動(dòng).
    2010-03-03
  • JS實(shí)現(xiàn)拖動(dòng)模糊框特效

    JS實(shí)現(xiàn)拖動(dòng)模糊框特效

    這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)拖動(dòng)模糊框特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • 簡(jiǎn)單實(shí)現(xiàn)js上傳文件功能

    簡(jiǎn)單實(shí)現(xiàn)js上傳文件功能

    這篇文章主要教大家如何簡(jiǎn)單實(shí)現(xiàn)js上傳文件功能,代碼簡(jiǎn)單,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 使用JavaScript實(shí)現(xiàn)小球按照貝塞爾曲線運(yùn)動(dòng)

    使用JavaScript實(shí)現(xiàn)小球按照貝塞爾曲線運(yùn)動(dòng)

    要在 JavaScript 中實(shí)現(xiàn)一個(gè)按照貝塞爾曲線運(yùn)動(dòng)的小球,關(guān)鍵是要掌握貝塞爾公式的基本原理和實(shí)現(xiàn)方式,以及使用 JavaScript 處理動(dòng)畫(huà)和物理運(yùn)算,感興趣的小伙伴跟著小編一起來(lái)看看吧
    2024-10-10
  • 淺談JavaScript中this的指向更改

    淺談JavaScript中this的指向更改

    這篇文章主要介紹了淺談JavaScript中this的指向更改,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評(píng)論