另一個實際 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 的狀態是甚麼。