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

DNS, Lock, NoSQL vs SQL and ACID

DNS, Lock, NoSQL vs SQL and ACID

一起來了解 Web Authentication

一起來了解 Web Authentication

HTB Blackfiled Walkthrough

HTB Blackfiled Walkthrough


Comments