Fetch 與 Promise (四):淺談 Promise


Posted by s103071049 on 2021-07-10

另一個實際 webApi 會用到 promise。

navigator.clipboard.readText().then(text => {
  console.log(text)
})

未來會有更多非同步操作都用 promise。處理非同步,要馬使用 call back function,要馬用 promise,使用 call back function,需要注意 call back 的參數怎麼傳,如果是 promise 就是 .then 只是參數一樣要看文件就是了。

自己做 promise 物件

想要達成的樣子

const myPromise
myPromise.then(() => {

})

新增一個 promise new Promise(函式),函式裡面的參數又是函式,分別是 resolve, reject,代表我想要我的 promises 的回傳值是甚麼。想要回傳東西時,call resolve,想要出一個錯誤時,call reject。

結果:data 3

function init(resolve, reject) {
  resolve(3)
}
const myPromise = new Promise(init)
myPromise.then((data) => {
  console.log('data', data)
})

結果:err 3

function init(resolve, reject) {
  reject(3)
}
const myPromise = new Promise(init)
myPromise.then((data) => {
  console.log('data', data)
}).catch(err => {
  console.log('err', err)
})

因為是 function 的參數,resolve, reject 也可以隨便調,他並不會影響 promise 的運行。

進行簡化

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

體現 promise 非同步,3 秒後才會 resolve,.then 裡面的 function 才會執行到。

const myPromise = new Promise( (resolve, reject) => {
  setTimeout( () => {
    resolve()
  }, 3000)
})
myPromise.then((data) => {
  console.log('data', data)
}).catch(err => {
  console.log('err', err)
})

setTimeout 的第一個 function 是 call back function,三秒過後再呼叫這個函式,然後再 call resolve()

所以它其實是 setTimeout(resolve, 3000),不是這樣喔 setTimeout(resolve(), 3000),這樣的話我就直接呼叫了。

const myPromise = new Promise( (resolve, reject) => {
  setTimeout(resolve, 3000)
})
myPromise.then((data) => {
  console.log('data', data)
}).catch(err => {
  console.log('err', err)
})

這樣變成 sleep 這個函式會回傳一個 promise,所以下面改成 sleep 執行
function,因為 sleep 是一個 function 所以執行完 function 才會得到 promise。回傳一個過 1000 毫秒才會 resolve 的 promise 出現。

function sleep(ms) {
  const myPromise = new Promise( (resolve, reject) => {
    setTimeout(resolve, ms)
  })
  return myPromise
}

sleep(1000).then((data) => {
  console.log('data', data)
}).catch(err => {
  console.log('err', err)
})

我宣告一個變數,回傳它。其實就等於直接將我要的 promise 回傳回去,功能完全不變。

function sleep(ms) {
  return  new Promise( (resolve, reject) => {
    setTimeout(resolve, ms)
  })
}

也可以轉成箭頭函式的寫法,如果箭頭函式只有一行,也不需要 return 與大括號。又因為 resolve 裡面也只有一行,所以還可以再將大括號拿掉

const sleep = ms => {
  return  new Promise( (resolve, reject) => {
    setTimeout(resolve, ms)
  })
}

const sleep = ms =>  new Promise( (resolve, reject) => {
  setTimeout(resolve, ms)
})

const sleep = ms =>
  new Promise( (resolve, reject) => setTimeout(resolve, ms))

回傳完一個 promise,它會幫你執行完 promise 再進入 .then

const sleep = ms =>
  new Promise( (resolve, reject) => setTimeout(resolve, ms))

sleep(500).then((data) => {
  console.log('data', data)
  return sleep(500)
}).then(data2 => {
  console.log(data2)
})
.catch(err => {
  console.log('err', err)
})

promise 有幾個狀態,一旦 resolve 或 reject,它的狀態就不會改變了。

結果:只會執行 .then() 不會執行到 .catch,一旦呼叫 resolve 它的狀態就是 resolve()

const myPromise = new Promise( (resolve, reject) => {
  setTimeout( () => {
    resolve()
    reject()
  }, 3000)
})
myPromise.then((data) => {
  console.log('data', data)
}).catch(err => {
  console.log('err', err)
})

第一個 data 會是 123,第二個 data 會是 456

const myPromise = new Promise( (resolve, reject) => {
  resolve(123)
})
const p2 = new Promise(resolve => {
  resolve(456)
})
myPromise.then((data) => {
  console.log('data1', data)
  return p2
}).then( (data) => {
  console.log('data2', data)
})
.catch(err => {
  console.log('err', err)
})

將 xhr 包成 promise,裡面可以放任何非同步的事情(同步也可以),用 resolve, reject 將資料傳回去
結果:myPromise data {test: "okok"}

const myPromise = new Promise( (resolve, reject) => {
  let request = new XMLHttpRequest();
  request.open('GET', 'https://run.mocky.io/v3/c3eca63b-2cbd-4b74-bdab-ccc32767c7d0', true)

  request.onload = function() {
    if (this.status >= 200 && this.status < 400) {
      let data = JSON.parse(this.response)
      resolve(data)
    }
  }
  request.onerror = function(err) {
    reject(err)
  }
  request.send();
})

myPromise.then((data) => {
  console.log('myPromise data', data)
})
.catch(err => {
  console.log('err', err)
})

小結、

promise 的基本使用

透過 new Promise 給他一個 function ,function 裡它會給我 resolve 跟 reject 兩個參數(type === function),透過呼叫這兩個函式去決定 promise 的狀態是甚麼。










Related Posts

【單元測試的藝術】Chap 5: 隔離(模擬)框架

【單元測試的藝術】Chap 5: 隔離(模擬)框架

文字方向 - 垂直/水平 文字書寫

文字方向 - 垂直/水平 文字書寫

[ 筆記 ] JavaScript - 02 函式

[ 筆記 ] JavaScript - 02 函式


Comments