1.promise特點(diǎn)
1.promise有三個(gè)狀態(tài) 成功態(tài)(resolve) 失敗態(tài)(reject) 等待態(tài)(pending)(既不成功也不失?。?br> 舉個(gè)例子,女友叫你給她買包 買 不買 不說(shuō)話
promise就是一個(gè)類,所以要new。promise默認(rèn)為pending狀態(tài)。
2.用戶自己決定成功和失敗的原因,也決定最后是否成功還是失敗
let promise = new Promise((resolve, reject) => {
//意思就是這里可以寫業(yè)務(wù)代碼,自己決定什么情況是失敗什么是成功
})
console.log(promise)
3.promise默認(rèn)執(zhí)行器立即執(zhí)行 !!!
let promise = new Promise((resolve, reject) => {
console.log(1)
})
console.log(2)
//結(jié)果是1,2
4.Promise的實(shí)例都有一個(gè)then方法,一個(gè)參數(shù)是成功的回調(diào),一個(gè)是失敗的回調(diào)
let promise = new Promise((resolve, reject) => {
console.log(1)
// resolve('成功')
})
promise.then((data) => {
console.log('success', data)
}, (err) => {
console.log('fail', err)
})
//結(jié)果 1
這里既沒(méi)有拋出成功也沒(méi)有拋出失敗,所以不會(huì)執(zhí)行后面的相關(guān)回調(diào)。
5.如果執(zhí)行函數(shù)是發(fā)生了異常也會(huì)執(zhí)行錯(cuò)誤的邏輯
let promise = new Promise((resolve, reject) => {
throw new Error('失敗了');
})
promise.then((data) => {
console.log('success', data)
}, (err) => {
console.log('fail', err)
})
//結(jié)果 : fail 失敗了
6.promise一旦成功了就不能失敗了,一旦失敗了就不能成功了
2.手寫promise
根據(jù)上面的特點(diǎn)手寫promise
2.1簡(jiǎn)單的promise
const RESOLVE = 'RESOLVE';
const REJECT = 'REJECT';
const PENDING = 'PENDING';
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
//resolve和reject不屬于實(shí)例上的
let resolve = (value) => {
if (this.status === PENDING) {
this.value = value;
this.status = RESOLVE;
}
}
let reject = (reason) => {
if (this.status === PENDING) {
this.reason = reason;
this.status = REJECT;
}
}
try {
executor(resolve, reject); //立即執(zhí)行并傳入resolve和reject
} catch (error) {
//錯(cuò)誤處理 就直接走錯(cuò)誤邏輯
reject(error);
}
}
then(onFufilled, onRejected) {
if (this.status === RESOLVE) {
onFufilled(this.value)
}
if (this.status === REJECT) {
onRejected(this.reason)
}
}
}
2.2promise的then方法
但是上面的then方法是有缺陷的,處理有異步的方法是有問(wèn)題的,例如執(zhí)行下面的代碼就會(huì)出問(wèn)題文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-552142.html
let Promise = require('./promise')
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1000);
})
promise.then((data) => {
console.log('success', data)
}, (err) => {
console.log('fail', err)
})
代碼執(zhí)行的結(jié)果是什么都不會(huì)打印出來(lái)的
因?yàn)閠hen方法里剛開始的狀態(tài)是pending,但是之前的代碼中是沒(méi)有對(duì)狀態(tài)為pending的進(jìn)行處理的,所以是不會(huì)有什么邏輯走的,而且1秒過(guò)后狀態(tài)變?yōu)閞esolve,但是又不會(huì)再執(zhí)行方法了的。
所以我們需要做的就是第一,把pending狀態(tài)的進(jìn)行區(qū)分;第二,等轉(zhuǎn)換為resolve或則reject狀態(tài)的話還能在執(zhí)行then方法。
第二種我們要使用發(fā)布訂閱模式。
將上述代碼改造:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-552142.html
const RESOLVE = 'RESOLVE';
const REJECT = 'REJECT';
const PENDING = 'PENDING';
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = []; //用來(lái)存放成功的回調(diào)
this.onREjectedCallbacks = []; //用來(lái)存放失敗的回調(diào)
//resolve和reject不屬于實(shí)例上的
let resolve = (value) => {
if (this.status === PENDING) {
this.value = value;
this.status = RESOLVE;
this.onResolvedCallbacks.forEach(fn => fn())
}
}
let reject = (reason) => {
if (this.status === PENDING) {
this.reason = reason;
this.status = REJECT;
this.onREjectedCallbacks.forEach(fn => fn())
}
}
try {
executor(resolve, reject); //立即執(zhí)行并傳入resolve和reject
} catch (error) {
//錯(cuò)誤處理 就直接走錯(cuò)誤邏輯
reject(error);
}
}
then(onFufilled, onRejected) {
if (this.status === RESOLVE) {
onFufilled(this.value)
}
if (this.status === REJECT) {
onRejected(this.reason)
}
if(this.status === PENDING){
this.onResolvedCallbacks.push(() =>{
onFufilled(this.value)
})
this.onREjectedCallbacks.push(() =>{
onRejected(this.reason)
})
console.log('等待')
}
}
}
module.exports = Promise
到了這里,關(guān)于promise學(xué)習(xí)1-promise特點(diǎn),手寫簡(jiǎn)易版promise的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!