簡單理解 Promise 的實(shí)現(xiàn)原理+自己手寫一個(gè) Promise

文章內(nèi)容輸出來源:拉勾教育大前端高薪訓(xùn)練營
文章說明:文章內(nèi)容為學(xué)習(xí)筆記吓坚,學(xué)徒之心,僅為分享; 如若有誤是牢,請?jiān)谠u論區(qū)指出僵井,如若您覺得文章內(nèi)容對您有一點(diǎn)點(diǎn)幫助,請點(diǎn)贊驳棱、關(guān)注批什、評論,共享

上一篇:JavaScript 深度剖析

簡單理解 Promise 的實(shí)現(xiàn)原理+自己手寫一個(gè) Promise

面試中社搅,經(jīng)常會(huì)被問到的問題:能否自己手動(dòng)寫一個(gè) Promise驻债,或者 Promise 內(nèi)部是如何實(shí)現(xiàn)異步調(diào)用的?

1形葬、你是否馬上想到合呐,完了不會(huì)啊 o(╥﹏╥)o,直接用笙以,還不一定用的明白呢淌实,內(nèi)部代碼如何實(shí)現(xiàn)的,鬼知道哇?
2猖腕、或者你也會(huì)想拆祈,管它內(nèi)部怎么實(shí)現(xiàn)的,拿來直接用不就完事了倘感,又不影響自己的代碼編程 →_→

可是面試官特別喜歡問這樣的問題放坏,你回答不上來,那么這次的面試基本也就沒有希望了【體現(xiàn)面試官很牛的樣子老玛,實(shí)際上面試官也不一定會(huì)淤年。。蜡豹∑侗矗】
但是下面的內(nèi)容恒傻,可以讓你成功實(shí)現(xiàn)一個(gè)自己手寫的 Promise鹰霍, 解決面試中的一問三不知的情況

進(jìn)入正題

要使用 Promise镜沽,首先要?jiǎng)?chuàng)建一個(gè) Promise 對象才行炊昆,
那么如何創(chuàng)建 Promise 對象桨吊?需要通過 new 關(guān)鍵字去執(zhí)行 Promise 就可以了

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

1、由上面的代碼可以看出 Promise 是一個(gè)類凤巨,在執(zhí)行這個(gè)類的時(shí)候视乐,需要傳遞一個(gè)執(zhí)行器函數(shù)進(jìn)去,同時(shí)這個(gè)執(zhí)行器函數(shù)是立即執(zhí)行的

2敢茁、執(zhí)行器函數(shù)里面的 2 個(gè)參數(shù) resolve佑淀、reject 其實(shí)是 2 個(gè)函數(shù),這 2 個(gè)函數(shù)的目的就是去更改 Promise 的狀態(tài)
resolve:fulfilled 把狀態(tài)更改為成功
reject: rejected 把狀態(tài)更改為失敗

3彰檬、在 Promise 中的狀態(tài)有 3 種:

  • pending 等待
  • fulfilled 成功
  • rejected 失敗
    Promise 中的狀態(tài)只能是由等待狀態(tài) 變成 成功狀態(tài) 或者 由等待狀態(tài) 變成 失敗狀態(tài)
    pending --> fulfilled
    pending --> rejected
    一旦狀態(tài)確定就不可更改

4伸刃、Promise 中的 then 方法內(nèi)部做的事情就是判斷 Promise 狀態(tài)谎砾,如果 Promise 狀態(tài)是成功,就調(diào)用 then()方法里面的成功的回調(diào)函數(shù)捧颅,也就是第一個(gè)函數(shù)景图,如果 Promise 狀態(tài)是失敗,就調(diào)用 then()方法里面的失敗的回調(diào)函數(shù)碉哑,也就是第二個(gè)函數(shù)挚币,then()方法石碑定義在原型對象中的

5、Promise 中的 then 方法內(nèi)成功的回調(diào)函數(shù)有一個(gè)參數(shù)扣典,表示成功之后的值妆毕,then 方法內(nèi)失敗的回調(diào)函數(shù)有一個(gè)參數(shù),表示失敗之后的值贮尖,

接下來按照上面的 5 點(diǎn)來創(chuàng)建最簡單的 Promise 原理的代碼

1笛粘、Promise 類核心邏輯實(shí)現(xiàn)

創(chuàng)建一個(gè) MyPromise.js 的文件,代碼如下:

const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗

class MyPromise {
  // 接收執(zhí)行器,執(zhí)行器是立即執(zhí)行的
  constructor(executor) {
    // 執(zhí)行器接收2個(gè)函數(shù)resolve远舅,reject闰蛔,這2個(gè)函數(shù)是用來更改promise的狀態(tài)的
    // 一旦promise狀態(tài)確定就不可更改
    executor(this.resolve, this.reject)
  }

  status = PENDING // promise的狀態(tài)
  value = undefined // 成功之后的值
  reason = undefined // 失敗之后的值

  // 用箭頭函數(shù)的原因是為了解決this的指向問題
  // resolve函數(shù)是用來更改promise的狀態(tài)的
  resolve = value => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    // promise的狀態(tài)更改為成功
    this.status = FULFILLED
    // 保存成功之后的值图柏,方便在then()方法中序六,拿到對應(yīng)的值
    this.value = value
  }

  // resolve函數(shù)是用來更改promise的狀態(tài)的
  reject = reason => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    // promise的狀態(tài)更改為失敗
    this.status = REJECTED
    // 保存成功之后的值蚤吹,方便在then()方法中例诀,拿到對應(yīng)的值
    this.reason = reason
  }

  then(sucessCallback, failCallback) {
    // 判斷promise的狀態(tài)
    if (this.status === FULFILLED) {
      // 成功的回調(diào),同時(shí)把成功的值傳遞給sucessCallback
      // 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
      sucessCallback(this.value)
    } else if (this.status === REJECTED) {
      // 失敗的回調(diào)裁着,同時(shí)把失敗的值傳遞給failCallback
      // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
      failCallback(this.reason)
    }
  }
}

module.exports = MyPromise

創(chuàng)建一個(gè) index.js 文件繁涂,文件內(nèi)導(dǎo)入 MyPromise.js 的文件,同時(shí)使用該文件二驰,代碼如下:

const MyPromise = require('./MyPromise')
let p1 = new MyPromise((resolve, reject) => {
  resolve('成功')
  // reject('失敗')
})
p1.then(
  value => {
    console.log(value)
  },
  reason => {
    console.log(reason)
  }
)

這樣最簡單的 Promise 就創(chuàng)建完成了

2扔罪、在 Promise 類中加入異步邏輯

創(chuàng)建一個(gè) MyPromise.js 的文件,代碼如下:

const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗

class MyPromise {
  constructor(executor) {
    executor(this.resolve, this.reject)
  }

  status = PENDING
  value = undefined
  reason = undefined
  sucessCallback = undefined // then()方法里面的成功的回調(diào)
  failCallback = undefined // then()方法里面的失敗的回調(diào)

  resolve = value => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候桶雀,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    this.status = FULFILLED
    this.value = value
    // 異步執(zhí)行矿酵,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    if (this.sucessCallback) {
      this.sucessCallback(this.value)
    }
  }

  reject = reason => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候矗积,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    this.status = REJECTED
    this.reason = reason
    // 異步執(zhí)行全肮,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    if (this.failCallback) {
      this.failCallback(this.reason)
    }
  }

  then(sucessCallback, failCallback) {
    if (this.status === FULFILLED) {
      sucessCallback
      sucessCallback(this.value)
    } else if (this.status === REJECTED) {
      failCallback
      failCallback(this.reason)
    } else {
      // 異步執(zhí)行棘捣,2秒后在執(zhí)行辜腺,來確定promise的狀態(tài)是成功還是失敗
      // 因?yàn)閳?zhí)行器是同時(shí)執(zhí)行的,然后執(zhí)行器在執(zhí)行的時(shí)候,發(fā)現(xiàn)自身里面沒有找到promise的狀態(tài)评疗,
      // 這時(shí)在執(zhí)行then()的時(shí)候测砂,then()方法不知道應(yīng)該調(diào)用成功的回調(diào)還是失敗的回調(diào)
      // 所以then()方法里面打印出來的是空
      // then()方法不知道應(yīng)該調(diào)用成功的回調(diào)還是失敗的回調(diào)的時(shí)候,
      // 先把sucessCallback, failCallback,給保存起來
      // 2秒后壤巷,就可以確認(rèn)調(diào)用resolve()還是reject()函數(shù)邑彪,
      // 同時(shí)把值傳遞給then()方法里面的對應(yīng)的成功的回調(diào)或者失敗的回調(diào)
      this.sucessCallback = sucessCallback
      this.failCallback = failCallback
    }
  }
}

module.exports = MyPromise

創(chuàng)建一個(gè) index.js 文件,文件內(nèi)導(dǎo)入 MyPromise.js 的文件胧华,同時(shí)使用該文件寄症,代碼如下:

const MyPromise = require('./MyPromise')
let p1 = new MyPromise((resolve, reject) => {
  // 異步執(zhí)行,2秒后在執(zhí)行矩动,來確定promise的狀態(tài)是成功還是失敗
  // 因?yàn)閳?zhí)行器是同時(shí)執(zhí)行的有巧,然后執(zhí)行器在執(zhí)行的時(shí)候,發(fā)現(xiàn)自身里面沒有找到promise的狀態(tài)悲没,
  // 這時(shí)在執(zhí)行then()的時(shí)候篮迎,then()方法不知道應(yīng)該調(diào)用成功的回調(diào)還是失敗的回調(diào)
  // 所以then()方法里面打印出來的是空
  // 然后去MyPromise.js文件中處理異步請求的情況
  setTimeout(() => {
    resolve('成功')
    // reject('失敗')
  }, 2000)
})
p1.then(
  value => {
    console.log(value)
  },
  reason => {
    console.log(reason)
  }
)

3、在 Promise 類中實(shí)現(xiàn) then 方法的多次調(diào)用示姿,添加多個(gè)處理函數(shù)

創(chuàng)建一個(gè) MyPromise.js 的文件甜橱,代碼如下:

const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗

class MyPromise {
  constructor(executor) {
    executor(this.resolve, this.reject)
  }

  status = PENDING
  value = undefined
  reason = undefined
  sucessCallback = [] // then()方法里面的成功的回調(diào)
  failCallback = [] // then()方法里面的失敗的回調(diào)

  resolve = value => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    this.status = FULFILLED
    this.value = value
    // 異步執(zhí)行栈戳,2秒后在執(zhí)行岂傲,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.sucessCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      // this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.sucessCallback.shift()(this.value)
    }
  }

  reject = reason => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    this.status = REJECTED
    this.reason = reason
    // 異步執(zhí)行子檀,2秒后在執(zhí)行镊掖,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.failCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      //  this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.failCallback.shift()(this.reason)
    }
  }

  then(sucessCallback, failCallback) {
    if (this.status === FULFILLED) {
      sucessCallback
      sucessCallback(this.value)
    } else if (this.status === REJECTED) {
      failCallback
      failCallback(this.reason)
    } else {
      // 異步執(zhí)行,2秒后在執(zhí)行褂痰,來確定promise的狀態(tài)是成功還是失敗
      // 因?yàn)槎啻握{(diào)用 then 方法亩进,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào),
      // 用數(shù)組保存起來才可以
      this.sucessCallback.push(sucessCallback)
      this.failCallback.push(failCallback)
    }
  }
}

module.exports = MyPromise

創(chuàng)建一個(gè) index.js 文件缩歪,文件內(nèi)導(dǎo)入 MyPromise.js 的文件归薛,同時(shí)使用該文件,代碼如下:

const MyPromise = require('./MyPromise')
let p1 = new MyPromise((resolve, reject) => {
  // 異步執(zhí)行匪蝙,2秒后在執(zhí)行主籍,來確定promise的狀態(tài)是成功還是失敗
  setTimeout(() => {
    resolve('異步執(zhí)行,成功')
    // reject('異步執(zhí)行骗污,失敗')
  }, 2000)
  // resolve('成功')
  // reject('失敗')
})

// then方法被調(diào)用了3次
p1.then(
  value => {
    console.log(value)
  },
  reason => {
    console.log(reason)
  }
)
p1.then(
  value => {
    console.log(value)
  },
  reason => {
    console.log(reason)
  }
)
p1.then(
  value => {
    console.log(value)
  },
  reason => {
    console.log(reason)
  }
)

4、在 Promise 類中實(shí)現(xiàn) then 方法的鏈?zhǔn)秸{(diào)用一

創(chuàng)建一個(gè) MyPromise.js 的文件沈条,代碼如下:

const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗

class MyPromise {
  constructor(executor) {
    executor(this.resolve, this.reject)
  }

  status = PENDING
  value = undefined
  reason = undefined
  sucessCallback = [] // then()方法里面的成功的回調(diào)
  failCallback = [] // then()方法里面的失敗的回調(diào)

  resolve = value => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候需忿,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    this.status = FULFILLED
    this.value = value
    // 異步執(zhí)行,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.sucessCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      // this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.sucessCallback.shift()(this.value)
    }
  }

  reject = reason => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候屋厘,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    this.status = REJECTED
    this.reason = reason
    // 異步執(zhí)行涕烧,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.failCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      //  this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.failCallback.shift()(this.reason)
    }
  }

  then(sucessCallback, failCallback) {
    let promise2 = new MyPromise((resolve2, reject2) => {
      // MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
      // 下面的代碼也必須立即執(zhí)行汗洒,所以正好放在執(zhí)行器函數(shù)里面
      // 判斷promise的狀態(tài)
      if (this.status === FULFILLED) {
        // 成功的回調(diào)议纯,同時(shí)把成功的值傳遞給sucessCallback
        // 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
        let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
        resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
      } else if (this.status === REJECTED) {
        // 失敗的回調(diào),同時(shí)把失敗的值傳遞給failCallback
        // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
        failCallback(this.reason)
      } else {
        // 異步執(zhí)行溢谤,2秒后在執(zhí)行瞻凤,來確定promise的狀態(tài)是成功還是失敗
        // 因?yàn)槎啻握{(diào)用 then 方法,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào)世杀,
        // 用數(shù)組保存起來才可以
        this.sucessCallback.push(sucessCallback)
        this.failCallback.push(failCallback)
      }
    })

    return promise2
  }
}

module.exports = MyPromise

創(chuàng)建一個(gè) index.js 文件阀参,文件內(nèi)導(dǎo)入 MyPromise.js 的文件,同時(shí)使用該文件瞻坝,代碼如下:

const MyPromise = require('./MyPromise')
let p1 = new MyPromise((resolve, reject) => {
  // 異步執(zhí)行蛛壳,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
  // setTimeout(() => {
  //   resolve('異步執(zhí)行所刀,成功')
  //   // reject('異步執(zhí)行衙荐,失敗')
  // }, 2000)
  resolve('成功')
  // reject('失敗')
})

// then方法的鏈?zhǔn)秸{(diào)用
// 后面then方法里面的回調(diào)函數(shù)拿到的值,是前一個(gè)then方法里面回調(diào)函數(shù)的返回值
// then方法是promise對象里的方法浮创,想要實(shí)現(xiàn)then方法的鏈?zhǔn)秸{(diào)用忧吟,
// 需要每一個(gè)then方法都要返回promise對象才可以
p1.then(
  value => {
    console.log(value)
    return 100
  },
  reason => {
    console.log(reason)
  }
).then(
  value => {
    console.log(value) // 100
  },
  reason => {
    console.log(reason)
  }
)

5、在 Promise 類中實(shí)現(xiàn) then 方法的鏈?zhǔn)秸{(diào)用二

創(chuàng)建一個(gè) MyPromise.js 的文件蒸矛,代碼如下:

const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗

class MyPromise {
  constructor(executor) {
    executor(this.resolve, this.reject)
  }

  status = PENDING
  value = undefined
  reason = undefined
  sucessCallback = [] // then()方法里面的成功的回調(diào)
  failCallback = [] // then()方法里面的失敗的回調(diào)

  resolve = value => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候瀑罗,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    this.status = FULFILLED
    this.value = value
    // 異步執(zhí)行,2秒后在執(zhí)行雏掠,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.sucessCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      // this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.sucessCallback.shift()(this.value)
    }
  }

  reject = reason => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候斩祭,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    this.status = REJECTED
    this.reason = reason
    // 異步執(zhí)行,2秒后在執(zhí)行乡话,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.failCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      //  this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.failCallback.shift()(this.reason)
    }
  }

  then(sucessCallback, failCallback) {
    let promise2 = new MyPromise((resolve2, reject2) => {
      // MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
      // 下面的代碼也必須立即執(zhí)行摧玫,所以正好放在執(zhí)行器函數(shù)里面
      // 判斷promise的狀態(tài)
      if (this.status === FULFILLED) {
        // 成功的回調(diào),同時(shí)把成功的值傳遞給sucessCallback
        // 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
        // 判斷X值是普通值還是promise對象
        // 如果是普通值 直接調(diào)用resolve
        // 如果是promise對象绑青,查看promise對象返回的結(jié)果
        // 再根據(jù)peomise對象返回的結(jié)果
        // 決定調(diào)用resolve 還是調(diào)用reject
        let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
        resolvePromise(x, resolve2, reject2)
        // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
      } else if (this.status === REJECTED) {
        // 失敗的回調(diào)诬像,同時(shí)把失敗的值傳遞給failCallback
        // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
        failCallback(this.reason)
      } else {
        // 異步執(zhí)行,2秒后在執(zhí)行闸婴,來確定promise的狀態(tài)是成功還是失敗
        // 因?yàn)槎啻握{(diào)用 then 方法坏挠,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào),
        // 用數(shù)組保存起來才可以
        this.sucessCallback.push(sucessCallback)
        this.failCallback.push(failCallback)
      }
    })

    return promise2
  }
}
// x 是前一個(gè)then方法里面的回調(diào)的返回值
function resolvePromise(x, resolve2, reject2) {
  if (x instanceof MyPromise) {
    // x 是promise對象
    // x.then((value) => resolve2(value), (reason) => reject2(reason))
    x.then(resolve2, reject2)
  } else {
    // x 是普通值
    resolve2(x)
  }
}
module.exports = MyPromise

創(chuàng)建一個(gè) index.js 文件邪乍,文件內(nèi)導(dǎo)入 MyPromise.js 的文件降狠,同時(shí)使用該文件对竣,代碼如下:

const MyPromise = require('./MyPromise')
let p1 = new MyPromise((resolve, reject) => {
  // 異步執(zhí)行,2秒后在執(zhí)行榜配,來確定promise的狀態(tài)是成功還是失敗
  // setTimeout(() => {
  //   resolve('異步執(zhí)行否纬,成功')
  //   // reject('異步執(zhí)行,失敗')
  // }, 2000)
  resolve('成功')
  // reject('失敗')
})
function other() {
  return new MyPromise((resolve, reject) => {
    return resolve('other')
  })
}
// then方法的鏈?zhǔn)秸{(diào)用
// 后面then方法里面的回調(diào)函數(shù)拿到的值蛋褥,是前一個(gè)then方法里面回調(diào)函數(shù)的返回值
// then方法是promise對象里的方法临燃,想要實(shí)現(xiàn)then方法的鏈?zhǔn)秸{(diào)用,
// 需要每一個(gè)then方法都要返回promise對象才可以
p1.then(
  value => {
    console.log(value)
    return other()
  },
  reason => {
    console.log(reason)
    // return other()
  }
).then(
  value => {
    console.log(value) // other
  },
  reason => {
    console.log(reason)
  }
)

6烙心、then 方法鏈?zhǔn)秸{(diào)用識別 Promise 對象自返回

創(chuàng)建一個(gè) MyPromise.js 的文件膜廊,代碼如下:

const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗

class MyPromise {
  constructor(executor) {
    executor(this.resolve, this.reject)
  }

  status = PENDING
  value = undefined
  reason = undefined
  sucessCallback = [] // then()方法里面的成功的回調(diào)
  failCallback = [] // then()方法里面的失敗的回調(diào)

  resolve = value => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    this.status = FULFILLED
    this.value = value
    // 異步執(zhí)行弃理,2秒后在執(zhí)行溃论,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.sucessCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      // this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.sucessCallback.shift()(this.value)
    }
  }

  reject = reason => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    this.status = REJECTED
    this.reason = reason
    // 異步執(zhí)行痘昌,2秒后在執(zhí)行钥勋,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.failCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      //  this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.failCallback.shift()(this.reason)
    }
  }

  then(sucessCallback, failCallback) {
    let promise2 = new MyPromise((resolve2, reject2) => {
      // MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
      // 下面的代碼也必須立即執(zhí)行,所以正好放在執(zhí)行器函數(shù)里面
      // 判斷promise的狀態(tài)
      if (this.status === FULFILLED) {
        // 成功的回調(diào)辆苔,同時(shí)把成功的值傳遞給sucessCallback
        // 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
        // 判斷X值是普通值還是promise對象
        // 如果是普通值 直接調(diào)用resolve
        // 如果是promise對象算灸,查看promise對象返回的結(jié)果
        // 再根據(jù)peomise對象返回的結(jié)果
        // 決定調(diào)用resolve 還是調(diào)用reject
        let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
        resolvePromise(x, resolve2, reject2)
        // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
      } else if (this.status === REJECTED) {
        // 失敗的回調(diào),同時(shí)把失敗的值傳遞給failCallback
        // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
        failCallback(this.reason)
      } else {
        // 異步執(zhí)行驻啤,2秒后在執(zhí)行菲驴,來確定promise的狀態(tài)是成功還是失敗
        // 因?yàn)槎啻握{(diào)用 then 方法,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào)骑冗,
        // 用數(shù)組保存起來才可以
        this.sucessCallback.push(sucessCallback)
        this.failCallback.push(failCallback)
      }
    })

    return promise2
  }
}
// x 是前一個(gè)then方法里面的回調(diào)的返回值
function resolvePromise(x, resolve2, reject2) {
  if (x instanceof MyPromise) {
    // x 是promise對象
    // x.then((value) => resolve2(value), (reason) => reject2(reason))
    x.then(resolve2, reject2)
  } else {
    // x 是普通值
    resolve2(x)
  }
}
module.exports = MyPromise

創(chuàng)建一個(gè) index.js 文件赊瞬,文件內(nèi)導(dǎo)入 MyPromise.js 的文件,同時(shí)使用該文件贼涩,代碼如下:

const MyPromise = require('./MyPromise')
let p1 = new MyPromise((resolve, reject) => {
  // 異步執(zhí)行巧涧,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
  // setTimeout(() => {
  //   resolve('異步執(zhí)行遥倦,成功')
  //   // reject('異步執(zhí)行谤绳,失敗')
  // }, 2000)
  resolve('成功')
  // reject('失敗')
})
function other() {
  return new MyPromise((resolve, reject) => {
    return resolve('other')
  })
}
// then方法的鏈?zhǔn)秸{(diào)用
// 后面then方法里面的回調(diào)函數(shù)拿到的值,是前一個(gè)then方法里面回調(diào)函數(shù)的返回值
// then方法是promise對象里的方法袒哥,想要實(shí)現(xiàn)then方法的鏈?zhǔn)秸{(diào)用缩筛,
// 需要每一個(gè)then方法都要返回promise對象才可以
p1.then(
  value => {
    console.log(value)
    return other()
  },
  reason => {
    console.log(reason)
    // return other()
  }
).then(
  value => {
    console.log(value) // other
  },
  reason => {
    console.log(reason)
  }
)

7、捕獲錯(cuò)誤及 then 鏈?zhǔn)秸{(diào)用其他狀態(tài)代碼補(bǔ)充

創(chuàng)建一個(gè) MyPromise.js 的文件堡称,代碼如下:

const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗

class MyPromise {
  // 接收執(zhí)行器,執(zhí)行器是立即執(zhí)行的
  constructor(executor) {
    // 執(zhí)行器接收2個(gè)函數(shù)resolve瞎抛,reject,這2個(gè)函數(shù)是用來更改promise的狀態(tài)的
    // 一旦promise狀態(tài)確定就不可更改
    try {
      executor(this.resolve, this.reject)
    } catch (error) {
      this.reject(error)
    }
    // executor(this.resolve, this.reject)
  }

  status = PENDING // promise的狀態(tài)
  value = undefined // 成功之后的值
  reason = undefined // 失敗之后的值
  sucessCallback = [] // then()方法里面的成功的回調(diào)
  failCallback = [] // then()方法里面的失敗的回調(diào)

  // 用箭頭函數(shù)的原因是為了解決this的指向問題
  // resolve函數(shù)是用來更改promise的狀態(tài)的
  resolve = value => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候却紧,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    // promise的狀態(tài)更改為成功
    this.status = FULFILLED
    // 保存成功之后的值桐臊,方便在then()方法中钞艇,拿到對應(yīng)的值
    this.value = value
    // 異步執(zhí)行,2秒后在執(zhí)行豪硅,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.sucessCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      //  this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.sucessCallback.shift()()
    }
  }

  // resolve函數(shù)是用來更改promise的狀態(tài)的
  reject = reason => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    // promise的狀態(tài)更改為失敗
    this.status = REJECTED
    // 保存成功之后的值挺物,方便在then()方法中懒浮,拿到對應(yīng)的值
    this.reason = reason
    // 異步執(zhí)行,2秒后在執(zhí)行识藤,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.failCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      //  this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.failCallback.shift()()
    }
  }

  then(sucessCallback, failCallback) {
    let promise2 = new MyPromise((resolve2, reject2) => {
      // MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
      // 下面的代碼也必須立即執(zhí)行砚著,所以正好放在執(zhí)行器函數(shù)里面
      // 判斷promise的狀態(tài)
      if (this.status === FULFILLED) {
        setTimeout(() => {
          try {
            // 成功的回調(diào),同時(shí)把成功的值傳遞給sucessCallback
            // 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
            // 判斷X值是普通值還是promise對象
            // 如果是普通值 直接調(diào)用resolve
            // 如果是promise對象痴昧,查看promise對象返回的結(jié)果
            // 再根據(jù)peomise對象返回的結(jié)果
            // 決定調(diào)用resolve 還是調(diào)用reject
            let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
            resolvePromise(promise2, x, resolve2, reject2)
            // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
          } catch (error) {
            reject2(error)
          }
        }, 0)
      } else if (this.status === REJECTED) {
        // 失敗的回調(diào)稽穆,同時(shí)把失敗的值傳遞給failCallback
        // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
        // failCallback(this.reason)
        setTimeout(() => {
          try {
            // 失敗的回調(diào),同時(shí)把失敗的值傳遞給failCallback
            // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
            // 判斷X值是普通值還是promise對象
            // 如果是普通值 直接調(diào)用resolve
            // 如果是promise對象赶撰,查看promise對象返回的結(jié)果
            // 再根據(jù)peomise對象返回的結(jié)果
            // 決定調(diào)用resolve 還是調(diào)用reject
            let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
            resolvePromise(promise2, x, resolve2, reject2)
            // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
          } catch (error) {
            reject2(error)
          }
        }, 0)
      } else {
        // 異步執(zhí)行舌镶,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
        // 因?yàn)槎啻握{(diào)用 then 方法豪娜,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào)餐胀,
        // 用數(shù)組保存起來才可以
        // this.sucessCallback.push(sucessCallback)
        // this.failCallback.push(failCallback)
        this.sucessCallback.push(() => {
          // sucessCallback()
          setTimeout(() => {
            try {
              // 成功的回調(diào),同時(shí)把成功的值傳遞給sucessCallback
              // 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
              // 判斷X值是普通值還是promise對象
              // 如果是普通值 直接調(diào)用resolve
              // 如果是promise對象瘤载,查看promise對象返回的結(jié)果
              // 再根據(jù)peomise對象返回的結(jié)果
              // 決定調(diào)用resolve 還是調(diào)用reject
              let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
              resolvePromise(promise2, x, resolve2, reject2)
              // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
            } catch (error) {
              reject2(error)
            }
          }, 0)
        })
        this.failCallback.push(() => {
          // failCallback()
          setTimeout(() => {
            try {
              // 失敗的回調(diào)否灾,同時(shí)把失敗的值傳遞給failCallback
              // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
              // 判斷X值是普通值還是promise對象
              // 如果是普通值 直接調(diào)用resolve
              // 如果是promise對象,查看promise對象返回的結(jié)果
              // 再根據(jù)peomise對象返回的結(jié)果
              // 決定調(diào)用resolve 還是調(diào)用reject
              let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
              resolvePromise(promise2, x, resolve2, reject2)
              // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
            } catch (error) {
              reject2(error)
            }
          }, 0)
        })
      }
    })

    return promise2
  }
}

// x 是前一個(gè)then方法里面的回調(diào)的返回值
function resolvePromise(promise2, x, resolve2, reject2) {
  if (promise2 === x) {
    return reject2(
      new TypeError('Chaining cycle detected for promise #<Promise>')
    )
  }
  if (x instanceof MyPromise) {
    // x 是promise對象
    // x.then((value) => resolve2(value), (reason) => reject2(reason))
    x.then(resolve2, reject2)
  } else {
    // x 是普通值
    resolve2(x)
  }
}

module.exports = MyPromise

創(chuàng)建一個(gè) index.js 文件鸣奔,文件內(nèi)導(dǎo)入 MyPromise.js 的文件墨技,同時(shí)使用該文件,代碼如下:

const MyPromise = require('./MyPromise')
let p1 = new MyPromise((resolve, reject) => {
  // 異步執(zhí)行挎狸,2秒后在執(zhí)行扣汪,來確定promise的狀態(tài)是成功還是失敗
  setTimeout(() => {
    resolve('異步執(zhí)行,成功')
    // reject('異步執(zhí)行伟叛,失敗')
  }, 2000)
  // resolve('成功')
  // throw new Error('執(zhí)行器錯(cuò)誤')
  // reject('失敗')
})

function other() {
  return new MyPromise((resolve, reject) => {
    return resolve('other')
  })
}
// then方法的鏈?zhǔn)秸{(diào)用
// 后面then方法里面的回調(diào)函數(shù)拿到的值私痹,是前一個(gè)then方法里面回調(diào)函數(shù)的返回值
// then方法是promise對象里的方法撤嫩,想要實(shí)現(xiàn)then方法的鏈?zhǔn)秸{(diào)用蹋订,
// 需要每一個(gè)then方法都要返回promise對象才可以
p1.then(
  value => {
    console.log(value)
    // throw new Error('第一個(gè)then拋出錯(cuò)誤')
  },
  reason => {
    console.log(reason)
    // return 10000
  }
).then(
  value => {
    console.log(value)
  },
  reason => {
    console.log(reason)
    // return other()
  }
)


8幽纷、將 then 方法的參數(shù)變成可選參數(shù)

創(chuàng)建一個(gè) MyPromise.js 的文件缘滥,代碼如下:

const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗

class MyPromise {
  // 接收執(zhí)行器,執(zhí)行器是立即執(zhí)行的
  constructor(executor) {
    // 執(zhí)行器接收2個(gè)函數(shù)resolve敦第,reject摧茴,這2個(gè)函數(shù)是用來更改promise的狀態(tài)的
    // 一旦promise狀態(tài)確定就不可更改
    try {
      executor(this.resolve, this.reject)
    } catch (error) {
      this.reject(error)
    }
    // executor(this.resolve, this.reject)
  }

  status = PENDING // promise的狀態(tài)
  value = undefined // 成功之后的值
  reason = undefined // 失敗之后的值
  sucessCallback = [] // then()方法里面的成功的回調(diào)
  failCallback = [] // then()方法里面的失敗的回調(diào)

  // 用箭頭函數(shù)的原因是為了解決this的指向問題
  // resolve函數(shù)是用來更改promise的狀態(tài)的
  resolve = value => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候彰导,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    // promise的狀態(tài)更改為成功
    this.status = FULFILLED
    // 保存成功之后的值矢腻,方便在then()方法中鞭衩,拿到對應(yīng)的值
    this.value = value
    // 異步執(zhí)行学搜,2秒后在執(zhí)行娃善,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.sucessCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      //  this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.sucessCallback.shift()()
    }
  }

  // resolve函數(shù)是用來更改promise的狀態(tài)的
  reject = reason => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    // promise的狀態(tài)更改為失敗
    this.status = REJECTED
    // 保存成功之后的值瑞佩,方便在then()方法中聚磺,拿到對應(yīng)的值
    this.reason = reason
    // 異步執(zhí)行,2秒后在執(zhí)行炬丸,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.failCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      //  this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.failCallback.shift()()
    }
  }

  then(sucessCallback, failCallback) {
    // 主要代碼在這里
    sucessCallback = sucessCallback ? sucessCallback : value => value
    failCallback = failCallback
      ? failCallback
      : reason => {
          throw reason
        }
    let promise2 = new MyPromise((resolve2, reject2) => {
      // MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
      // 下面的代碼也必須立即執(zhí)行瘫寝,所以正好放在執(zhí)行器函數(shù)里面
      // 判斷promise的狀態(tài)
      if (this.status === FULFILLED) {
        setTimeout(() => {
          try {
            // 成功的回調(diào),同時(shí)把成功的值傳遞給sucessCallback
            // 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
            // 判斷X值是普通值還是promise對象
            // 如果是普通值 直接調(diào)用resolve
            // 如果是promise對象稠炬,查看promise對象返回的結(jié)果
            // 再根據(jù)peomise對象返回的結(jié)果
            // 決定調(diào)用resolve 還是調(diào)用reject
            let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
            resolvePromise(promise2, x, resolve2, reject2)
            // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
          } catch (error) {
            reject2(error)
          }
        }, 0)
      } else if (this.status === REJECTED) {
        // 失敗的回調(diào)焕阿,同時(shí)把失敗的值傳遞給failCallback
        // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
        // failCallback(this.reason)
        setTimeout(() => {
          try {
            // 失敗的回調(diào),同時(shí)把失敗的值傳遞給failCallback
            // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
            // 判斷X值是普通值還是promise對象
            // 如果是普通值 直接調(diào)用resolve
            // 如果是promise對象首启,查看promise對象返回的結(jié)果
            // 再根據(jù)peomise對象返回的結(jié)果
            // 決定調(diào)用resolve 還是調(diào)用reject
            let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
            resolvePromise(promise2, x, resolve2, reject2)
            // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
          } catch (error) {
            reject2(error)
          }
        }, 0)
      } else {
        // 異步執(zhí)行暮屡,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
        // 因?yàn)槎啻握{(diào)用 then 方法毅桃,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào)褒纲,
        // 用數(shù)組保存起來才可以
        // this.sucessCallback.push(sucessCallback)
        // this.failCallback.push(failCallback)
        this.sucessCallback.push(() => {
          // sucessCallback()
          setTimeout(() => {
            try {
              // 成功的回調(diào),同時(shí)把成功的值傳遞給sucessCallback
              // 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
              // 判斷X值是普通值還是promise對象
              // 如果是普通值 直接調(diào)用resolve
              // 如果是promise對象钥飞,查看promise對象返回的結(jié)果
              // 再根據(jù)peomise對象返回的結(jié)果
              // 決定調(diào)用resolve 還是調(diào)用reject
              let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
              resolvePromise(promise2, x, resolve2, reject2)
              // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
            } catch (error) {
              reject2(error)
            }
          }, 0)
        })
        this.failCallback.push(() => {
          // failCallback()
          setTimeout(() => {
            try {
              // 失敗的回調(diào)外厂,同時(shí)把失敗的值傳遞給failCallback
              // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
              // 判斷X值是普通值還是promise對象
              // 如果是普通值 直接調(diào)用resolve
              // 如果是promise對象,查看promise對象返回的結(jié)果
              // 再根據(jù)peomise對象返回的結(jié)果
              // 決定調(diào)用resolve 還是調(diào)用reject
              let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
              resolvePromise(promise2, x, resolve2, reject2)
              // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
            } catch (error) {
              reject2(error)
            }
          }, 0)
        })
      }
    })

    return promise2
  }
}

// x 是前一個(gè)then方法里面的回調(diào)的返回值
function resolvePromise(promise2, x, resolve2, reject2) {
  if (promise2 === x) {
    return reject2(
      new TypeError('Chaining cycle detected for promise #<Promise>')
    )
  }
  if (x instanceof MyPromise) {
    // x 是promise對象
    // x.then((value) => resolve2(value), (reason) => reject2(reason))
    x.then(resolve2, reject2)
  } else {
    // x 是普通值
    resolve2(x)
  }
}

module.exports = MyPromise


創(chuàng)建一個(gè) index.js 文件代承,文件內(nèi)導(dǎo)入 MyPromise.js 的文件汁蝶,同時(shí)使用該文件,代碼如下:

const MyPromise = require('./MyPromise')
let p1 = new MyPromise((resolve, reject) => {
  // 異步執(zhí)行论悴,2秒后在執(zhí)行掖棉,來確定promise的狀態(tài)是成功還是失敗
  // resolve('成功')
  reject('失敗')
})

// then方法的鏈?zhǔn)秸{(diào)用
// 后面then方法里面的回調(diào)函數(shù)拿到的值,是前一個(gè)then方法里面回調(diào)函數(shù)的返回值
// then方法是promise對象里的方法膀估,想要實(shí)現(xiàn)then方法的鏈?zhǔn)秸{(diào)用幔亥,
// 需要每一個(gè)then方法都要返回promise對象才可以
p1.then() // 等同于then((value)=>value)
  .then() // 等同于then((value)=>value)
  .then(
    value => {
      console.log(value)
    },
    reason => {
      console.log(reason)
    }
  )

9、Promise.all([])方法的實(shí)現(xiàn)

創(chuàng)建一個(gè) MyPromise.js 的文件察纯,代碼如下:

const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗

class MyPromise {
  // 接收執(zhí)行器,執(zhí)行器是立即執(zhí)行的
  constructor(executor) {
    // 執(zhí)行器接收2個(gè)函數(shù)resolve帕棉,reject,這2個(gè)函數(shù)是用來更改promise的狀態(tài)的
    // 一旦promise狀態(tài)確定就不可更改
    try {
      executor(this.resolve, this.reject)
    } catch (error) {
      this.reject(error)
    }
    // executor(this.resolve, this.reject)
  }

  status = PENDING // promise的狀態(tài)
  value = undefined // 成功之后的值
  reason = undefined // 失敗之后的值
  sucessCallback = [] // then()方法里面的成功的回調(diào)
  failCallback = [] // then()方法里面的失敗的回調(diào)

  // 用箭頭函數(shù)的原因是為了解決this的指向問題
  // resolve函數(shù)是用來更改promise的狀態(tài)的
  resolve = value => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候饼记,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    // promise的狀態(tài)更改為成功
    this.status = FULFILLED
    // 保存成功之后的值香伴,方便在then()方法中,拿到對應(yīng)的值
    this.value = value
    // 異步執(zhí)行具则,2秒后在執(zhí)行即纲,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.sucessCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      //  this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.sucessCallback.shift()()
    }
  }

  // resolve函數(shù)是用來更改promise的狀態(tài)的
  reject = reason => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    // promise的狀態(tài)更改為失敗
    this.status = REJECTED
    // 保存成功之后的值博肋,方便在then()方法中低斋,拿到對應(yīng)的值
    this.reason = reason
    // 異步執(zhí)行蜂厅,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.failCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      //  this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.failCallback.shift()()
    }
  }

  then(sucessCallback, failCallback) {
    // 主要代碼在這里
    sucessCallback = sucessCallback ? sucessCallback : value => value
    failCallback = failCallback
      ? failCallback
      : reason => {
          throw reason
        }
    let promise2 = new MyPromise((resolve2, reject2) => {
      // MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
      // 下面的代碼也必須立即執(zhí)行膊畴,所以正好放在執(zhí)行器函數(shù)里面
      // 判斷promise的狀態(tài)
      if (this.status === FULFILLED) {
        setTimeout(() => {
          try {
            // 成功的回調(diào)掘猿,同時(shí)把成功的值傳遞給sucessCallback
            // 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
            // 判斷X值是普通值還是promise對象
            // 如果是普通值 直接調(diào)用resolve
            // 如果是promise對象,查看promise對象返回的結(jié)果
            // 再根據(jù)peomise對象返回的結(jié)果
            // 決定調(diào)用resolve 還是調(diào)用reject
            let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
            resolvePromise(promise2, x, resolve2, reject2)
            // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
          } catch (error) {
            reject2(error)
          }
        }, 0)
      } else if (this.status === REJECTED) {
        // 失敗的回調(diào)唇跨,同時(shí)把失敗的值傳遞給failCallback
        // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
        // failCallback(this.reason)
        setTimeout(() => {
          try {
            // 失敗的回調(diào)术奖,同時(shí)把失敗的值傳遞給failCallback
            // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
            // 判斷X值是普通值還是promise對象
            // 如果是普通值 直接調(diào)用resolve
            // 如果是promise對象,查看promise對象返回的結(jié)果
            // 再根據(jù)peomise對象返回的結(jié)果
            // 決定調(diào)用resolve 還是調(diào)用reject
            let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
            resolvePromise(promise2, x, resolve2, reject2)
            // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
          } catch (error) {
            reject2(error)
          }
        }, 0)
      } else {
        // 異步執(zhí)行轻绞,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
        // 因?yàn)槎啻握{(diào)用 then 方法佣耐,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào)政勃,
        // 用數(shù)組保存起來才可以
        // this.sucessCallback.push(sucessCallback)
        // this.failCallback.push(failCallback)
        this.sucessCallback.push(() => {
          // sucessCallback()
          setTimeout(() => {
            try {
              // 成功的回調(diào),同時(shí)把成功的值傳遞給sucessCallback
              // 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
              // 判斷X值是普通值還是promise對象
              // 如果是普通值 直接調(diào)用resolve
              // 如果是promise對象兼砖,查看promise對象返回的結(jié)果
              // 再根據(jù)peomise對象返回的結(jié)果
              // 決定調(diào)用resolve 還是調(diào)用reject
              let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
              resolvePromise(promise2, x, resolve2, reject2)
              // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
            } catch (error) {
              reject2(error)
            }
          }, 0)
        })
        this.failCallback.push(() => {
          // failCallback()
          setTimeout(() => {
            try {
              // 失敗的回調(diào)奸远,同時(shí)把失敗的值傳遞給failCallback
              // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
              // 判斷X值是普通值還是promise對象
              // 如果是普通值 直接調(diào)用resolve
              // 如果是promise對象,查看promise對象返回的結(jié)果
              // 再根據(jù)peomise對象返回的結(jié)果
              // 決定調(diào)用resolve 還是調(diào)用reject
              let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
              resolvePromise(promise2, x, resolve2, reject2)
              // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
            } catch (error) {
              reject2(error)
            }
          }, 0)
        })
      }
    })

    return promise2
  }

  // 靜態(tài)方法讽挟,由類本身來調(diào)用
  static all(array) {
    let result = []
    let index = 0

    return new MyPromise((resolve, reject) => {
      function addData(key, value) {
        result[key] = value
        index++
        if (index === array.length) {
          resolve(result)
        }
      }

      for (let index = 0; index < array.length; index++) {
        // 拿到當(dāng)前值
        let current = array[index]
        if (current instanceof MyPromise) {
          // promise對象
          current.then(
            value => addData(index, value),
            reason => reject(reason)
          )
        } else {
          // 普通值
          addData(index, array[index])
        }
      }
    })
  }
}

// x 是前一個(gè)then方法里面的回調(diào)的返回值
function resolvePromise(promise2, x, resolve2, reject2) {
  if (promise2 === x) {
    return reject2(
      new TypeError('Chaining cycle detected for promise #<Promise>')
    )
  }
  if (x instanceof MyPromise) {
    // x 是promise對象
    // x.then((value) => resolve2(value), (reason) => reject2(reason))
    x.then(resolve2, reject2)
  } else {
    // x 是普通值
    resolve2(x)
  }
}

module.exports = MyPromise

創(chuàng)建一個(gè) index.js 文件懒叛,文件內(nèi)導(dǎo)入 MyPromise.js 的文件,同時(shí)使用該文件耽梅,代碼如下:

const MyPromise = require('./MyPromise')

function p1() {
  return new MyPromise((resolve, reject) => {
    // 異步執(zhí)行薛窥,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
    setTimeout(() => {
      resolve('p1')
      // reject('失敗')
    }, 2000)
  })
}
function p2() {
  return new MyPromise((resolve, reject) => {
    // 異步執(zhí)行眼姐,2秒后在執(zhí)行诅迷,來確定promise的狀態(tài)是成功還是失敗
    resolve('p2')
    // reject('失敗')
  })
}

MyPromise.all(['a', 'b', p1(), p2(), 'c']).then(
  value => {
    // value ==> ['a', 'b', 'p1', 'p2', 'c']
    console.log(value)
  },
  error => {
    console.log(error)
  }
)

10、Promise.resolve 方法的實(shí)現(xiàn)

創(chuàng)建一個(gè) MyPromise.js 的文件众旗,代碼如下:

const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗

class MyPromise {
  // 接收執(zhí)行器,執(zhí)行器是立即執(zhí)行的
  constructor(executor) {
    // 執(zhí)行器接收2個(gè)函數(shù)resolve罢杉,reject,這2個(gè)函數(shù)是用來更改promise的狀態(tài)的
    // 一旦promise狀態(tài)確定就不可更改
    try {
      executor(this.resolve, this.reject)
    } catch (error) {
      this.reject(error)
    }
    // executor(this.resolve, this.reject)
  }

  status = PENDING // promise的狀態(tài)
  value = undefined // 成功之后的值
  reason = undefined // 失敗之后的值
  sucessCallback = [] // then()方法里面的成功的回調(diào)
  failCallback = [] // then()方法里面的失敗的回調(diào)

  // 用箭頭函數(shù)的原因是為了解決this的指向問題
  // resolve函數(shù)是用來更改promise的狀態(tài)的
  resolve = value => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候贡歧,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    // promise的狀態(tài)更改為成功
    this.status = FULFILLED
    // 保存成功之后的值滩租,方便在then()方法中,拿到對應(yīng)的值
    this.value = value
    // 異步執(zhí)行利朵,2秒后在執(zhí)行律想,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.sucessCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      //  this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.sucessCallback.shift()()
    }
  }

  // resolve函數(shù)是用來更改promise的狀態(tài)的
  reject = reason => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    // promise的狀態(tài)更改為失敗
    this.status = REJECTED
    // 保存成功之后的值绍弟,方便在then()方法中蜘欲,拿到對應(yīng)的值
    this.reason = reason
    // 異步執(zhí)行,2秒后在執(zhí)行晌柬,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.failCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      //  this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.failCallback.shift()()
    }
  }

  then(sucessCallback, failCallback) {
    // 主要代碼在這里
    sucessCallback = sucessCallback ? sucessCallback : value => value
    failCallback = failCallback
      ? failCallback
      : reason => {
          throw reason
        }
    let promise2 = new MyPromise((resolve2, reject2) => {
      // MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
      // 下面的代碼也必須立即執(zhí)行姥份,所以正好放在執(zhí)行器函數(shù)里面
      // 判斷promise的狀態(tài)
      if (this.status === FULFILLED) {
        setTimeout(() => {
          try {
            // 成功的回調(diào)郭脂,同時(shí)把成功的值傳遞給sucessCallback
            // 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
            // 判斷X值是普通值還是promise對象
            // 如果是普通值 直接調(diào)用resolve
            // 如果是promise對象,查看promise對象返回的結(jié)果
            // 再根據(jù)peomise對象返回的結(jié)果
            // 決定調(diào)用resolve 還是調(diào)用reject
            let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
            resolvePromise(promise2, x, resolve2, reject2)
            // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
          } catch (error) {
            reject2(error)
          }
        }, 0)
      } else if (this.status === REJECTED) {
        // 失敗的回調(diào)澈歉,同時(shí)把失敗的值傳遞給failCallback
        // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
        // failCallback(this.reason)
        setTimeout(() => {
          try {
            // 失敗的回調(diào)展鸡,同時(shí)把失敗的值傳遞給failCallback
            // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
            // 判斷X值是普通值還是promise對象
            // 如果是普通值 直接調(diào)用resolve
            // 如果是promise對象,查看promise對象返回的結(jié)果
            // 再根據(jù)peomise對象返回的結(jié)果
            // 決定調(diào)用resolve 還是調(diào)用reject
            let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
            resolvePromise(promise2, x, resolve2, reject2)
            // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
          } catch (error) {
            reject2(error)
          }
        }, 0)
      } else {
        // 異步執(zhí)行埃难,2秒后在執(zhí)行莹弊,來確定promise的狀態(tài)是成功還是失敗
        // 因?yàn)槎啻握{(diào)用 then 方法,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào)涡尘,
        // 用數(shù)組保存起來才可以
        // this.sucessCallback.push(sucessCallback)
        // this.failCallback.push(failCallback)
        this.sucessCallback.push(() => {
          // sucessCallback()
          setTimeout(() => {
            try {
              // 成功的回調(diào)忍弛,同時(shí)把成功的值傳遞給sucessCallback
              // 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
              // 判斷X值是普通值還是promise對象
              // 如果是普通值 直接調(diào)用resolve
              // 如果是promise對象,查看promise對象返回的結(jié)果
              // 再根據(jù)peomise對象返回的結(jié)果
              // 決定調(diào)用resolve 還是調(diào)用reject
              let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
              resolvePromise(promise2, x, resolve2, reject2)
              // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
            } catch (error) {
              reject2(error)
            }
          }, 0)
        })
        this.failCallback.push(() => {
          // failCallback()
          setTimeout(() => {
            try {
              // 失敗的回調(diào)考抄,同時(shí)把失敗的值傳遞給failCallback
              // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
              // 判斷X值是普通值還是promise對象
              // 如果是普通值 直接調(diào)用resolve
              // 如果是promise對象细疚,查看promise對象返回的結(jié)果
              // 再根據(jù)peomise對象返回的結(jié)果
              // 決定調(diào)用resolve 還是調(diào)用reject
              let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
              resolvePromise(promise2, x, resolve2, reject2)
              // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
            } catch (error) {
              reject2(error)
            }
          }, 0)
        })
      }
    })

    return promise2
  }

  // 靜態(tài)方法,由類本身來調(diào)用
  static all(array) {
    let result = []
    let index = 0

    return new MyPromise((resolve, reject) => {
      function addData(key, value) {
        result[key] = value
        index++
        if (index === array.length) {
          resolve(result)
        }
      }

      for (let index = 0; index < array.length; index++) {
        // 拿到當(dāng)前值
        let current = array[index]
        if (current instanceof MyPromise) {
          // promise對象
          current.then(
            value => addData(index, value),
            reason => reject(reason)
          )
        } else {
          // 普通值
          addData(index, array[index])
        }
      }
    })
  }
  // 靜態(tài)方法川梅,由類本身來調(diào)用
  static resolve(value) {
    // 傳入的值value是否為promise對象疯兼?
    if (value instanceof MyPromise) {
      // 傳入的值value是promise對象
      return value
    } else {
      // 傳入的值,就是普通的值
      return new MyPromise(resolve => resolve(value))
    }
  }
}

// x 是前一個(gè)then方法里面的回調(diào)的返回值
function resolvePromise(promise2, x, resolve2, reject2) {
  if (promise2 === x) {
    return reject2(
      new TypeError('Chaining cycle detected for promise #<Promise>')
    )
  }
  if (x instanceof MyPromise) {
    // x 是promise對象
    // x.then((value) => resolve2(value), (reason) => reject2(reason))
    x.then(resolve2, reject2)
  } else {
    // x 是普通值
    resolve2(x)
  }
}

module.exports = MyPromise

創(chuàng)建一個(gè) index.js 文件贫途,文件內(nèi)導(dǎo)入 MyPromise.js 的文件吧彪,同時(shí)使用該文件,代碼如下:

const MyPromise = require('./MyPromise')

function p1() {
  return new MyPromise((resolve, reject) => {
    // 異步執(zhí)行丢早,2秒后在執(zhí)行姨裸,來確定promise的狀態(tài)是成功還是失敗
    resolve('p1')
    // reject('失敗')
  })
}

MyPromise.resolve(10).then(value => console.log(value))
MyPromise.resolve(p1()).then(value => console.log(value))

11、finally 方法的實(shí)現(xiàn)

創(chuàng)建一個(gè) MyPromise.js 的文件怨酝,代碼如下:

const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗

class MyPromise {
  // 接收執(zhí)行器,執(zhí)行器是立即執(zhí)行的
  constructor(executor) {
    // 執(zhí)行器接收2個(gè)函數(shù)resolve啦扬,reject,這2個(gè)函數(shù)是用來更改promise的狀態(tài)的
    // 一旦promise狀態(tài)確定就不可更改
    try {
      executor(this.resolve, this.reject)
    } catch (error) {
      this.reject(error)
    }
    // executor(this.resolve, this.reject)
  }

  status = PENDING // promise的狀態(tài)
  value = undefined // 成功之后的值
  reason = undefined // 失敗之后的值
  sucessCallback = [] // then()方法里面的成功的回調(diào)
  failCallback = [] // then()方法里面的失敗的回調(diào)

  // 用箭頭函數(shù)的原因是為了解決this的指向問題
  // resolve函數(shù)是用來更改promise的狀態(tài)的
  resolve = value => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候凫碌,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    // promise的狀態(tài)更改為成功
    this.status = FULFILLED
    // 保存成功之后的值扑毡,方便在then()方法中,拿到對應(yīng)的值
    this.value = value
    // 異步執(zhí)行盛险,2秒后在執(zhí)行瞄摊,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.sucessCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      //  this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.sucessCallback.shift()()
    }
  }

  // resolve函數(shù)是用來更改promise的狀態(tài)的
  reject = reason => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    // promise的狀態(tài)更改為失敗
    this.status = REJECTED
    // 保存成功之后的值苦掘,方便在then()方法中换帜,拿到對應(yīng)的值
    this.reason = reason
    // 異步執(zhí)行,2秒后在執(zhí)行鹤啡,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.failCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      //  this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.failCallback.shift()()
    }
  }

  then(sucessCallback, failCallback) {
    // 主要代碼在這里
    sucessCallback = sucessCallback ? sucessCallback : value => value
    failCallback = failCallback
      ? failCallback
      : reason => {
          throw reason
        }
    let promise2 = new MyPromise((resolve2, reject2) => {
      // MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
      // 下面的代碼也必須立即執(zhí)行惯驼,所以正好放在執(zhí)行器函數(shù)里面
      // 判斷promise的狀態(tài)
      if (this.status === FULFILLED) {
        setTimeout(() => {
          try {
            // 成功的回調(diào),同時(shí)把成功的值傳遞給sucessCallback
            // 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
            // 判斷X值是普通值還是promise對象
            // 如果是普通值 直接調(diào)用resolve
            // 如果是promise對象,查看promise對象返回的結(jié)果
            // 再根據(jù)peomise對象返回的結(jié)果
            // 決定調(diào)用resolve 還是調(diào)用reject
            let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
            resolvePromise(promise2, x, resolve2, reject2)
            // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
          } catch (error) {
            reject2(error)
          }
        }, 0)
      } else if (this.status === REJECTED) {
        // 失敗的回調(diào)祟牲,同時(shí)把失敗的值傳遞給failCallback
        // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
        // failCallback(this.reason)
        setTimeout(() => {
          try {
            // 失敗的回調(diào)隙畜,同時(shí)把失敗的值傳遞給failCallback
            // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
            // 判斷X值是普通值還是promise對象
            // 如果是普通值 直接調(diào)用resolve
            // 如果是promise對象,查看promise對象返回的結(jié)果
            // 再根據(jù)peomise對象返回的結(jié)果
            // 決定調(diào)用resolve 還是調(diào)用reject
            let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
            resolvePromise(promise2, x, resolve2, reject2)
            // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
          } catch (error) {
            reject2(error)
          }
        }, 0)
      } else {
        // 異步執(zhí)行说贝,2秒后在執(zhí)行议惰,來確定promise的狀態(tài)是成功還是失敗
        // 因?yàn)槎啻握{(diào)用 then 方法,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào)乡恕,
        // 用數(shù)組保存起來才可以
        // this.sucessCallback.push(sucessCallback)
        // this.failCallback.push(failCallback)
        this.sucessCallback.push(() => {
          // sucessCallback()
          setTimeout(() => {
            try {
              // 成功的回調(diào)言询,同時(shí)把成功的值傳遞給sucessCallback
              // 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
              // 判斷X值是普通值還是promise對象
              // 如果是普通值 直接調(diào)用resolve
              // 如果是promise對象,查看promise對象返回的結(jié)果
              // 再根據(jù)peomise對象返回的結(jié)果
              // 決定調(diào)用resolve 還是調(diào)用reject
              let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
              resolvePromise(promise2, x, resolve2, reject2)
              // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
            } catch (error) {
              reject2(error)
            }
          }, 0)
        })
        this.failCallback.push(() => {
          // failCallback()
          setTimeout(() => {
            try {
              // 失敗的回調(diào)傲宜,同時(shí)把失敗的值傳遞給failCallback
              // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
              // 判斷X值是普通值還是promise對象
              // 如果是普通值 直接調(diào)用resolve
              // 如果是promise對象运杭,查看promise對象返回的結(jié)果
              // 再根據(jù)peomise對象返回的結(jié)果
              // 決定調(diào)用resolve 還是調(diào)用reject
              let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
              resolvePromise(promise2, x, resolve2, reject2)
              // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
            } catch (error) {
              reject2(error)
            }
          }, 0)
        })
      }
    })

    return promise2
  }

  // 靜態(tài)方法,由類本身來調(diào)用
  static all(array) {
    let result = []
    let index = 0

    return new MyPromise((resolve, reject) => {
      function addData(key, value) {
        result[key] = value
        index++
        if (index === array.length) {
          resolve(result)
        }
      }

      for (let index = 0; index < array.length; index++) {
        // 拿到當(dāng)前值
        let current = array[index]
        if (current instanceof MyPromise) {
          // promise對象
          current.then(
            value => addData(index, value),
            reason => reject(reason)
          )
        } else {
          // 普通值
          addData(index, array[index])
        }
      }
    })
  }
  // 靜態(tài)方法函卒,由類本身來調(diào)用
  static resolve(value) {
    // 傳入的值value是否為promise對象辆憔?
    if (value instanceof MyPromise) {
      // 傳入的值value是promise對象
      return value
    } else {
      // 傳入的值,就是普通的值
      return new MyPromise(resolve => resolve(value))
    }
  }
  finally(callback) {
    return this.then(
      value => {
        return MyPromise.resolve(callback()).then(() => value)
        // callback()
        // return value
      },
      reason => {
        return MyPromise.resolve(callback()).then(() => {
          throw reason
        })
        // callback()
        // throw reason
      }
    )
  }
}

// x 是前一個(gè)then方法里面的回調(diào)的返回值
function resolvePromise(promise2, x, resolve2, reject2) {
  if (promise2 === x) {
    return reject2(
      new TypeError('Chaining cycle detected for promise #<Promise>')
    )
  }
  if (x instanceof MyPromise) {
    // x 是promise對象
    // x.then((value) => resolve2(value), (reason) => reject2(reason))
    x.then(resolve2, reject2)
  } else {
    // x 是普通值
    resolve2(x)
  }
}

module.exports = MyPromise

創(chuàng)建一個(gè) index.js 文件谆趾,文件內(nèi)導(dǎo)入 MyPromise.js 的文件,同時(shí)使用該文件叛本,代碼如下:

const MyPromise = require('./MyPromise')

function p1() {
  return new MyPromise((resolve, reject) => {
    // 異步執(zhí)行沪蓬,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
    setTimeout(() => {
      resolve('p1成功')
      // reject('p2失敗')
    }, 2000)
  })
}

function p2() {
  return new MyPromise((resolve, reject) => {
    resolve('p2成功')
    // reject('失敗')
  })
}

// finally()方法特點(diǎn):
// 1来候、無論promise對象的最終狀態(tài)是成功的跷叉,還是失敗的,finally方法中的回調(diào)函數(shù)始終會(huì)被執(zhí)行一次
// 2营搅、finally方法的后面可以使用鏈?zhǔn)秸{(diào)用then方法云挟,拿到當(dāng)前promise對象返回的結(jié)果
p2()
  .finally(() => {
    console.log('finally方法')
    return p1()
  })
  .then(
    value => console.log(value),
    reason => console.log(reason)
  )

12、catch 方法的實(shí)現(xiàn)

創(chuàng)建一個(gè) MyPromise.js 的文件转质,代碼如下:

const PENDING = 'pending' // promise的狀態(tài) 等待
const FULFILLED = 'fulfilled' // promise的狀態(tài) 成功
const REJECTED = 'rejected' // promise的狀態(tài) 失敗

class MyPromise {
  // 接收執(zhí)行器,執(zhí)行器是立即執(zhí)行的
  constructor(executor) {
    // 執(zhí)行器接收2個(gè)函數(shù)resolve园欣,reject,這2個(gè)函數(shù)是用來更改promise的狀態(tài)的
    // 一旦promise狀態(tài)確定就不可更改
    try {
      executor(this.resolve, this.reject)
    } catch (error) {
      this.reject(error)
    }
    // executor(this.resolve, this.reject)
  }

  status = PENDING // promise的狀態(tài)
  value = undefined // 成功之后的值
  reason = undefined // 失敗之后的值
  sucessCallback = [] // then()方法里面的成功的回調(diào)
  failCallback = [] // then()方法里面的失敗的回調(diào)

  // 用箭頭函數(shù)的原因是為了解決this的指向問題
  // resolve函數(shù)是用來更改promise的狀態(tài)的
  resolve = value => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候休蟹,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    // promise的狀態(tài)更改為成功
    this.status = FULFILLED
    // 保存成功之后的值沸枯,方便在then()方法中,拿到對應(yīng)的值
    this.value = value
    // 異步執(zhí)行赂弓,2秒后在執(zhí)行绑榴,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.sucessCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      //  this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.sucessCallback.shift()()
    }
  }

  // resolve函數(shù)是用來更改promise的狀態(tài)的
  reject = reason => {
    // promise的狀態(tài)不是等待狀態(tài)的時(shí)候,要阻止程序向下執(zhí)行
    if (this.status !== PENDING) return
    // promise的狀態(tài)更改為失敗
    this.status = REJECTED
    // 保存成功之后的值盈魁,方便在then()方法中翔怎,拿到對應(yīng)的值
    this.reason = reason
    // 異步執(zhí)行,2秒后在執(zhí)行,來確定promise的狀態(tài)是成功還是失敗
    // 然后 把值 傳遞給then()方法里面對應(yīng)的sucessCallback, failCallback函數(shù)
    while (this.failCallback.length) {
      // this.sucessCallback 里面存儲(chǔ)一個(gè)或多個(gè)then方法的sucessCallback, failCallback函數(shù)
      //  this.sucessCallback.shift() 就是每一個(gè)then方法對應(yīng)的sucessCallback, failCallback函數(shù)
      // 需要把每一個(gè)都取出來傳遞給對應(yīng)的then方法
      this.failCallback.shift()()
    }
  }

  then(sucessCallback, failCallback) {
    // 主要代碼在這里
    sucessCallback = sucessCallback ? sucessCallback : value => value
    failCallback = failCallback
      ? failCallback
      : reason => {
          throw reason
        }
    let promise2 = new MyPromise((resolve2, reject2) => {
      // MyPromise的執(zhí)行器函數(shù)是立即執(zhí)行的
      // 下面的代碼也必須立即執(zhí)行赤套,所以正好放在執(zhí)行器函數(shù)里面
      // 判斷promise的狀態(tài)
      if (this.status === FULFILLED) {
        setTimeout(() => {
          try {
            // 成功的回調(diào)飘痛,同時(shí)把成功的值傳遞給sucessCallback
            // 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
            // 判斷X值是普通值還是promise對象
            // 如果是普通值 直接調(diào)用resolve
            // 如果是promise對象,查看promise對象返回的結(jié)果
            // 再根據(jù)peomise對象返回的結(jié)果
            // 決定調(diào)用resolve 還是調(diào)用reject
            let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
            resolvePromise(promise2, x, resolve2, reject2)
            // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
          } catch (error) {
            reject2(error)
          }
        }, 0)
      } else if (this.status === REJECTED) {
        // 失敗的回調(diào)于毙,同時(shí)把失敗的值傳遞給failCallback
        // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
        // failCallback(this.reason)
        setTimeout(() => {
          try {
            // 失敗的回調(diào)敦冬,同時(shí)把失敗的值傳遞給failCallback
            // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
            // 判斷X值是普通值還是promise對象
            // 如果是普通值 直接調(diào)用resolve
            // 如果是promise對象,查看promise對象返回的結(jié)果
            // 再根據(jù)peomise對象返回的結(jié)果
            // 決定調(diào)用resolve 還是調(diào)用reject
            let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
            resolvePromise(promise2, x, resolve2, reject2)
            // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
          } catch (error) {
            reject2(error)
          }
        }, 0)
      } else {
        // 異步執(zhí)行唯沮,2秒后在執(zhí)行脖旱,來確定promise的狀態(tài)是成功還是失敗
        // 因?yàn)槎啻握{(diào)用 then 方法,所以需要把多個(gè)then方法里面的成功的回調(diào)和失敗的回調(diào)介蛉,
        // 用數(shù)組保存起來才可以
        // this.sucessCallback.push(sucessCallback)
        // this.failCallback.push(failCallback)
        this.sucessCallback.push(() => {
          // sucessCallback()
          setTimeout(() => {
            try {
              // 成功的回調(diào)萌庆,同時(shí)把成功的值傳遞給sucessCallback
              // 成功的值在調(diào)用resolve()的時(shí)候傳遞過來的
              // 判斷X值是普通值還是promise對象
              // 如果是普通值 直接調(diào)用resolve
              // 如果是promise對象,查看promise對象返回的結(jié)果
              // 再根據(jù)peomise對象返回的結(jié)果
              // 決定調(diào)用resolve 還是調(diào)用reject
              let x = sucessCallback(this.value) // 前一個(gè)then方法里面的回調(diào)的返回值
              resolvePromise(promise2, x, resolve2, reject2)
              // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
            } catch (error) {
              reject2(error)
            }
          }, 0)
        })
        this.failCallback.push(() => {
          // failCallback()
          setTimeout(() => {
            try {
              // 失敗的回調(diào)币旧,同時(shí)把失敗的值傳遞給failCallback
              // 失敗的值在調(diào)用reject()的時(shí)候傳遞過來的
              // 判斷X值是普通值還是promise對象
              // 如果是普通值 直接調(diào)用resolve
              // 如果是promise對象践险,查看promise對象返回的結(jié)果
              // 再根據(jù)peomise對象返回的結(jié)果
              // 決定調(diào)用resolve 還是調(diào)用reject
              let x = failCallback(this.reason) // 前一個(gè)then方法里面的回調(diào)的返回值
              resolvePromise(promise2, x, resolve2, reject2)
              // resolve2(x) // 把前一個(gè)then方法里面的回調(diào)的返回值x 傳遞給后一個(gè)then方法里面的回調(diào)函數(shù)中
            } catch (error) {
              reject2(error)
            }
          }, 0)
        })
      }
    })

    return promise2
  }

  // 靜態(tài)方法,由類本身來調(diào)用
  static all(array) {
    let result = []
    let index = 0

    return new MyPromise((resolve, reject) => {
      function addData(key, value) {
        result[key] = value
        index++
        if (index === array.length) {
          resolve(result)
        }
      }

      for (let index = 0; index < array.length; index++) {
        // 拿到當(dāng)前值
        let current = array[index]
        if (current instanceof MyPromise) {
          // promise對象
          current.then(
            value => addData(index, value),
            reason => reject(reason)
          )
        } else {
          // 普通值
          addData(index, array[index])
        }
      }
    })
  }
  // 靜態(tài)方法吹菱,由類本身來調(diào)用
  static resolve(value) {
    // 傳入的值value是否為promise對象巍虫?
    if (value instanceof MyPromise) {
      // 傳入的值value是promise對象
      return value
    } else {
      // 傳入的值,就是普通的值
      return new MyPromise(resolve => resolve(value))
    }
  }

  finally(callback) {
    return this.then(
      value => {
        return MyPromise.resolve(callback()).then(() => value)
        // callback()
        // return value
      },
      reason => {
        return MyPromise.resolve(callback()).then(() => {
          throw reason
        })
        // callback()
        // throw reason
      }
    )
  }
  catch(failCallback) {
    return this.then(undefined, failCallback)
  }
}

// x 是前一個(gè)then方法里面的回調(diào)的返回值
function resolvePromise(promise2, x, resolve2, reject2) {
  if (promise2 === x) {
    return reject2(
      new TypeError('Chaining cycle detected for promise #<Promise>')
    )
  }
  if (x instanceof MyPromise) {
    // x 是promise對象
    // x.then((value) => resolve2(value), (reason) => reject2(reason))
    x.then(resolve2, reject2)
  } else {
    // x 是普通值
    resolve2(x)
  }
}

module.exports = MyPromise

創(chuàng)建一個(gè) index.js 文件鳍刷,文件內(nèi)導(dǎo)入 MyPromise.js 的文件占遥,同時(shí)使用該文件,代碼如下:

const MyPromise = require('./MyPromise')

function p1() {
  return new MyPromise((resolve, reject) => {
    resolve('p1成功')
    reject('失敗')
  })
}

p1()
  .then(value => console.log(value))
  .catch(reason => console.log(reason))

結(jié)語:
拉鉤教育訓(xùn)練營學(xué)習(xí)已經(jīng)有二周了输瓜,在沒有來之前瓦胎,我都是回家之后打游戲(游戲名:斗戰(zhàn)神),來到這里之后才發(fā)現(xiàn)居然還有很多大佬也在學(xué)習(xí)尤揣,真的很驚訝搔啊,本人自身水平垃圾的一批,再不學(xué)習(xí)北戏,以后可能一直就是混吃等死的狀態(tài)了

  • 首先來說负芋,拉鉤的課程很干,每個(gè)視頻很短嗜愈,都是干貨示罗,講師沒有一句廢話,視頻內(nèi)容覆蓋比較廣芝硬,布置的作業(yè)也比較符合實(shí)際蚜点,導(dǎo)師也會(huì)及時(shí)批改,然后一周或兩周必有直播拌阴,直播都會(huì)回答學(xué)習(xí)過程中所遇到的問題和新的內(nèi)容
  • 其次來說绍绘,每個(gè)班都有班級群,群里居然還有5年6年的前端開發(fā)的大佬(⊙▽⊙); 班主任和導(dǎo)師也在群里陪拘,有任何問題都可以在群里@導(dǎo)師厂镇,班級群真的很活躍
  • 最后來說一句,如果有其他人也是在打游戲混日子左刽,不如來拉鉤教育訓(xùn)練營捺信,嘗試著改變一下自己目前所處的環(huán)境
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者欠痴。
  • 序言:七十年代末迄靠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子喇辽,更是在濱河造成了極大的恐慌掌挚,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件菩咨,死亡現(xiàn)場離奇詭異吠式,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)抽米,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門特占,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人云茸,你說我怎么就攤上這事是目。” “怎么了查辩?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵胖笛,是天一觀的道長网持。 經(jīng)常有香客問我宜岛,道長,這世上最難降的妖魔是什么功舀? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任萍倡,我火速辦了婚禮,結(jié)果婚禮上辟汰,老公的妹妹穿的比我還像新娘列敲。我一直安慰自己,他們只是感情好帖汞,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布戴而。 她就那樣靜靜地躺著,像睡著了一般翩蘸。 火紅的嫁衣襯著肌膚如雪所意。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機(jī)與錄音扶踊,去河邊找鬼泄鹏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛秧耗,可吹牛的內(nèi)容都是我干的备籽。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼分井,長吁一口氣:“原來是場噩夢啊……” “哼车猬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起杂抽,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤诈唬,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體翼悴,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡筷弦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了阅仔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡弧械,死狀恐怖八酒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情刃唐,我是刑警寧澤羞迷,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站画饥,受9級特大地震影響衔瓮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜抖甘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一热鞍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧衔彻,春花似錦薇宠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至柄沮,卻和暖如春回梧,著一層夾襖步出監(jiān)牢的瞬間逐工,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工漂辐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留泪喊,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓髓涯,卻偏偏與公主長得像袒啼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子纬纪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評論 2 353