国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

動(dòng)手搞一個(gè)Promise

shadajin / 1718人閱讀

摘要:一個(gè)后可以通過方法,指定和時(shí)的回調(diào)函數(shù)。構(gòu)造函數(shù)內(nèi)部要有一個(gè)值,用來保存上次執(zhí)行的結(jié)果值,如果報(bào)錯(cuò),則保存的是異常信息。因?yàn)槭且粋€(gè)構(gòu)造函數(shù),使用的寫法,首先想到的就是有顯式聲明的。

Javascript語言的執(zhí)行環(huán)境是"單線程"(single thread)。所謂"單線程",就是指一次只能完成一件任務(wù)。如果有多個(gè)任務(wù),就必須排隊(duì),前面一個(gè)任務(wù)完成,再執(zhí)行后面一個(gè)任務(wù),以此類推。

這種模式的好處是實(shí)現(xiàn)起來比較簡(jiǎn)單,執(zhí)行環(huán)境相對(duì)單純;壞處是只要有一個(gè)任務(wù)耗時(shí)很長(zhǎng),后面的任務(wù)都必須排隊(duì)等著,會(huì)拖延整個(gè)程序的執(zhí)行。常見的瀏覽器無響應(yīng)(假死),往往就是因?yàn)槟骋欢蜫avascript代碼長(zhǎng)時(shí)間運(yùn)行(比如死循環(huán)),導(dǎo)致整個(gè)頁面卡在這個(gè)地方,其他任務(wù)無法執(zhí)行。

為了解決這個(gè)問題,Javascript語言將任務(wù)的執(zhí)行模式分成兩種:同步(Synchronous)和異步(Asynchronous)。

異步模式"編程的4種方法:回調(diào)函數(shù)、事件監(jiān)聽、發(fā)布/訂閱、Promises對(duì)象
還有g(shù)enerator、async/await.

本文嘗試說一下對(duì)Promise的理解及如何實(shí)現(xiàn)。
1.Promise原理

promise對(duì)象有三種狀態(tài),pending、fulfilled和rejected。promise對(duì)象內(nèi)部保存一個(gè)需要執(zhí)行一段時(shí)間的異步操作,當(dāng)異步操作執(zhí)行結(jié)束后可以調(diào)用resolve或reject方法,來改變promise對(duì)象的狀態(tài),狀態(tài)一旦改變就不能再變。new一個(gè)promise后可以通過then方法,指定resolved和rejected時(shí)的回調(diào)函數(shù)。下面是我們?nèi)粘J褂肞romise的代碼邏輯。
let p = new Promise((resolve,reject)=>{

    $.ajax({
    url: "../www/data.txt",
    dataType: "json",
    success(data){
        resolve(data);
     },
    error(err){
        reject(err);
     }
   }); 
});
p.then(function(data){
    alert("success"+data);
},function(err){
    alert("failed");
})

結(jié)合Promise A+規(guī)范,我們就可以分析一下我們要實(shí)現(xiàn)一個(gè)什么東西:

實(shí)現(xiàn)一個(gè)狀態(tài)機(jī),有三個(gè)狀態(tài),pending、fulfilled、rejected,狀態(tài)之間的轉(zhuǎn)化只能是pending->fulfilled、pending->rejected,狀態(tài)變化不可逆。
實(shí)現(xiàn)一個(gè)then方法,可以用來設(shè)置成功和失敗的回調(diào)
then方法要能被調(diào)用多次,所以then方法需要每次返回一個(gè)新的promise對(duì)象,這樣才能支持鏈?zhǔn)秸{(diào)用。
構(gòu)造函數(shù)內(nèi)部要有一個(gè)value值,用來保存上次執(zhí)行的結(jié)果值,如果報(bào)錯(cuò),則保存的是異常信息。
2.實(shí)現(xiàn)原理

2.1實(shí)現(xiàn)狀態(tài)機(jī)

那我們現(xiàn)在就按照上面提到的原理和規(guī)范來實(shí)現(xiàn)這個(gè)Promise構(gòu)造函數(shù)。
class myPromise {

    constructor(executor) {
        this.status = PENDING;
        this.value = "";
        this.Resolve = this.resolve.bind(this);
        this.Reject = this.reject.bind(this);
        this.then= this.then.bind(this);
        executor(this.Resolve, this.Reject);
    }

    resolve(value) {
        if (this.status === PENDING) {
            this.value = value;
            this.status = FULFILLED;
        }
    }

    reject(value) {
        if (this.status === PENDING) {
            this.value = value;
            this.status = REJECTED;
        }
    }

    then(onfulfilled, onrejected) {
        if (this.status === FULFILLED) {
            onfulfilled(this.value);
        }
        if (this.status === REJECTED) {
            onrejected(this.value);
        }
    }
}

const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

const test = new myPromise((resolve, reject) => {
    resolve(100);
});
test.then((data) => {
    console.log(data);
}, (data) => {
});

因?yàn)镻romise是一個(gè)構(gòu)造函數(shù),使用ES6的寫法,首先想到的就是有顯式constructor聲明的class。上面就是我們用class的實(shí)現(xiàn),可以看到這樣我們就實(shí)現(xiàn)了這個(gè)狀態(tài)機(jī),有status, value兩個(gè)屬性和resolve, reject, then三個(gè)函數(shù);同時(shí)它有pending, fulfilled和rejected三個(gè)狀態(tài),其中pending就可以切換為fulfilled或者rejected兩種。

運(yùn)行一下,輸出了100,但是現(xiàn)在其實(shí)不是一個(gè)異步處理方案,代碼先運(yùn)行了resolve(100)然后又運(yùn)行了then函數(shù),其實(shí)對(duì)于異步的情況沒有處理,不信的話就給resolve加一個(gè)setTimeout,好了,代碼又沒有輸出了。

2.2 實(shí)現(xiàn)異步設(shè)置狀態(tài)

作為一個(gè)異步處理的函數(shù),在使用的時(shí)候,我們肯定是會(huì)先設(shè)置好不同異步返回后的處理邏輯(即then的成功、失敗調(diào)用函數(shù)),然后安心等待異步執(zhí)行,最后再異步結(jié)束后,系統(tǒng)會(huì)自動(dòng)根據(jù)我們的邏輯選擇調(diào)用不同回調(diào)函數(shù)。換句話說,then函數(shù)要對(duì)status為pending的狀態(tài)進(jìn)行處理。處理的原理是設(shè)置兩個(gè)數(shù)組,在pending狀態(tài)下分別保存成功和失敗回調(diào)函數(shù),當(dāng)狀態(tài)改變后,再根據(jù)狀態(tài)去調(diào)用數(shù)組中保存的回調(diào)函數(shù)。

class myPromise {
constructor (executor) {

this.status = PENDING;
this.value = "";
this.onfulfilledArr = [];
this.onrejectedArr = [];
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.then = this.then.bind(this);
executor(this.resolve, this.reject);

}

resolve (value) {

if (this.status === PENDING) {
  this.value = value;
  this.onfulfilledArr.forEach(item => {
    item(this.value);
  })
  this.status = FULFILLED; 
}

}

reject (value) {

if (this.status === PENDING) {
  this.value = value;
  this.onrejectedArr.forEach(item => {
    item(this.value);
  })
  this.status = REJECTED;
}

}

then (onfulfilled, onrejected) {

if (this.status === FULFILLED) {
  onfulfilled(this.value);
}
if (this.status === REJECTED) {
  onrejected(this.value);
}
if (this.status === PENDING) {
  this.onfulfilledArr.push(onfulfilled);
  this.onrejectedArr.push(onrejected);
}

}
}

const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

const test = new myPromise((resolve, reject) => {
setTimeout(() => {

resolve(100);

}, 2000)
});
test.then((data) => {
console.log(data);
},(data) => {});
可以這樣理解

new myPromise 有異步代碼

setTimeout(() => {
??? resolve(100);
}, 2000)

js是單線程的,這個(gè)時(shí)候會(huì)先把這個(gè)任務(wù)添加到定時(shí)觸發(fā)器線程中去(計(jì)時(shí)完畢后添加到事件隊(duì)列中,等待js引擎空閑后執(zhí)行),先去執(zhí)行下面的同步代碼
test.then((data) => {

??? console.log(data);

},(data) => {});
完成輸出及狀態(tài)改變。

但是Promise的一大特點(diǎn)就是可以鏈?zhǔn)秸{(diào)用,即test.then(success, fail).then(success, fail)...這就需要then返回一個(gè)新的Promise對(duì)象,而我們的程序現(xiàn)在明顯的是不支持的。那么繼續(xù)改一下。

2.3?實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用

再觀察一下鏈?zhǔn)秸{(diào)用,如果成功和失敗的函數(shù)中有返回值,這個(gè)值要作為參數(shù)傳給下個(gè)then函數(shù)的成功或失敗回調(diào)。所以我們要在返回的new Promise中調(diào)用相應(yīng)的函數(shù)。

class myPromise {
constructor (executor) {

this.status = PENDING;
this.value = "";
this.onfulfilledArr = [];
this.onrejectedArr = [];
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
this.then = this.then.bind(this);
executor(this.resolve, this.reject);

}

resolve (value) {

if (this.status === PENDING) {
  this.value = value;
  this.onfulfilledArr.forEach(item => {
    item(this.value);
  })
  this.status = FULFILLED; 
}

}

reject (value) {

if (this.status === PENDING) {
  this.value = value;
  this.onrejectedArr.forEach(item => {
    item(this.value);
  })
  this.status = REJECTED;
}

}

then (onfulfilled, onrejected) {

if (this.status === FULFILLED) {
  const res = onfulfilled(this.value);
  return new Promise(function(resolve, reject) {
    resolve(res);
  })
}
if (this.status === REJECTED) {
  const res = onrejected(this.value);
  return new Promise(function(resolve, reject) {
    reject(res);
  })
}
if (this.status === PENDING) {
  const self = this;
  return new Promise(function(resolve, reject) {
    self.onfulfilledArr.push(() => {
      const res = onfulfilled(self.value)
      resolve(res);
    });
    self.onrejectedArr.push(() => {
      const res = onrejected(self.value)
      reject(res);
    });
  })
}

}
}

const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

const test = new myPromise((resolve, reject) => {
setTimeout(() => {

resolve(100);

}, 2000)
});
test.then((data) => {
console.log(data);
return data + 5;
},(data) => {})
.then((data) => {
console.log(data)
},(data) => {});

再運(yùn)行一下,輸出100,105。好了,一個(gè)簡(jiǎn)單的Promise就實(shí)現(xiàn)好了。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/113705.html

相關(guān)文章

  • 動(dòng)手一個(gè)Promise

    摘要:一個(gè)后可以通過方法,指定和時(shí)的回調(diào)函數(shù)。構(gòu)造函數(shù)內(nèi)部要有一個(gè)值,用來保存上次執(zhí)行的結(jié)果值,如果報(bào)錯(cuò),則保存的是異常信息。因?yàn)槭且粋€(gè)構(gòu)造函數(shù),使用的寫法,首先想到的就是有顯式聲明的。 showImg(https://segmentfault.com/img/bVbffEu?w=530&h=253); Javascript語言的執(zhí)行環(huán)境是單線程(single thread)。所謂單線程,就...

    NervosNetwork 評(píng)論0 收藏0
  • 自己動(dòng)手實(shí)現(xiàn)一個(gè)Promise

    摘要:意味著操作成功完成。狀態(tài)的對(duì)象可能觸發(fā)狀態(tài)并傳遞一個(gè)值給相應(yīng)的狀態(tài)處理方法,也可能觸發(fā)失敗狀態(tài)并傳遞失敗信息。測(cè)試用例測(cè)試用例方法返回一個(gè)帶有拒絕原因參數(shù)的對(duì)象。 Promise基本用法 Promise 對(duì)象是一個(gè)代理對(duì)象,被代理的值在Promise對(duì)象創(chuàng)建時(shí)可能是未知的。 它允許你為異步操作的成功和失敗分別綁定相應(yīng)的處理方法(handlers)。 這讓異步方法可以像同步方法那樣返回值...

    Yujiaao 評(píng)論0 收藏0
  • 自己動(dòng)手,為vue寫一個(gè)jsonp的方法

    摘要:它之后能夠被使用到很多場(chǎng)景中其他處理請(qǐng)求和響應(yīng)的方式,甚至任何需要生成自己的響應(yīng)的方式。總結(jié)到這里都講完了,其實(shí)沒什么難度,主要是自己項(xiàng)目中遇到了,但是中沒有這個(gè)方法啊。所以就想著實(shí)現(xiàn)了一個(gè),因?yàn)槠渌姆椒ㄒ捕挤庋b,不差這一個(gè)了。 Fetch 提供了對(duì)?Request?和?Response?(以及其他與網(wǎng)絡(luò)請(qǐng)求有關(guān)的)對(duì)象通用的定義。它之后能夠被使用到很多場(chǎng)景中:service wor...

    dongxiawu 評(píng)論0 收藏0
  • JavaScript基礎(chǔ)——深入學(xué)習(xí)async/await

    摘要:等待的基本語法該關(guān)鍵字的的意思就是讓編譯器等待并返回結(jié)果。這里并不會(huì)占用資源,因?yàn)橐婵梢酝瑫r(shí)執(zhí)行其他任務(wù)其他腳本或處理事件。接下來,我們寫一個(gè)火箭發(fā)射場(chǎng)景的小例子不是真的發(fā)射火箭 本文由云+社區(qū)發(fā)表 本篇文章,小編將和大家一起學(xué)習(xí)異步編程的未來——async/await,它會(huì)打破你對(duì)上篇文章Promise的認(rèn)知,竟然異步代碼還能這么寫! 但是別太得意,你需要深入理解Promise后,...

    張金寶 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<