Promise
對象是由關鍵字 new
及其構造函數來建立的。該構造函數會把一個叫作「處理器函數」(executor function)的函數做爲它的參數。這個「處理器函數」接受兩個函數——resolve
和 reject
——做爲其參數。當異步任務順利完成且返回結果值時,會調用 resolve
函數;而當異步任務失敗且返回失敗緣由(一般是一個錯誤對象)時,會調用reject
函數。promise
const myFirstPromise = new Promise((resolve, reject) => { // ?異步操做,最終調用: // // resolve(someValue); // fulfilled // ?或 // reject("failure reason"); // rejected });
想要某個函數擁有promise功能,只需讓其返回一個promise便可異步
function myAsyncFunction(url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open("GET", url); xhr.onload = () => resolve(xhr.responseText); xhr.onerror = () => reject(xhr.statusText); xhr.send(); }); };
示例:函數
let myFirstPromise = new Promise(function (resolve, reject) { // 當異步代碼執行成功時,咱們纔會調用resolve(...), 當異步代碼失敗時就會調用reject(...) // 在本例中,咱們使用setTimeout(...)來模擬異步代碼,實際編碼時多是XHR請求或是HTML5的一些API方法. setTimeout(function () { resolve('成功!') // 代碼正常執行! }, 250) }) myFirstPromise.then(function (successMessage) { // successMessage的值是上面調用resolve(...)方法傳入的值. // successMessage參數不必定非要是字符串類型,這裏只是舉個例子 console.log('Yay! ' + successMessage) })
控制檯輸出打印的是 Yay! 成功!this
例子:編碼
用戶註冊以前須要填入正確的手機驗證碼。在用戶信息都填入完整以後點擊註冊時還需校驗驗證碼是否填寫正確url
// 驗證驗證碼 export function validCode (param) { return fdcJsonp(process.env.API_CODE, 'picgif.oauth.sms.verifycode', param) .then(res => { if (res.code === '200') { return res } }) .catch((err) => { return Promise.reject({ code: 'code.has.error', msg: err }) }) }
// 用戶註冊 export function registUser (params) { return fdcJsonp(process.env.API_ROOT_UC, 'ucaction.user.adduserbymobile', params) .then((res) => { return res }) .catch((err) => { return Promise.reject({ code: 'registed.has.failed', msg: err }) }) }
校驗註冊代碼邏輯以下:spa
validCode({ code: this.code, mobile: this.phone }) .then((res) => { if (res.code === '200') { if (this.isRegistering) { return } this.isRegistering = true this.$refs.registBtn.innerHTML = '正在註冊...' return registUser({ loginName: this.userName, mobileNum: this.phone, userPasswd: this.password, verifyCode: this.code, v: '2.0', userid: Cookie.get('uc_userInfo') registerFrom: getRegFrom(curUrl) }) } }) .then((res) => { let instance = Toast.success('註冊成功') setTimeout(() => { instance.close() this.$router.push('/') }, 2000) }) .catch((err) => { if (err.code) { switch (err.code) { case 'code.has.error': case 'registed.has.failed': Toast(err.msg) break } } this.btnName = '註冊' this.registerAllow = true })
一個 Promise
就是一個表明了異步操做最終完成或者失敗的對象. 一個promise可使用它的constructor建立。然而,大多數人都在使用由其餘函數建立並返回的promise。rest
promise替代了下面這種舊式的函數,這種舊式函數須要兩個回調函數,並最終調用處理成功事件或者處理失敗事件的回調函數:code
function successCallback(result) { console.log("It succeeded with " + result); } function failureCallback(error) { console.log("It failed with " + error); } doSomething(successCallback, failureCallback);
新式函數返回一個你能夠直接綁定回調函數的promise對象,來代替舊式的函數形式:router
let promise = doSomething();
promise.then(successCallback, failureCallback);
或者更簡單的形式:
doSomething().then(successCallback, failureCallback);
不像舊式函數那樣傳遞迴調函數,promise會帶來一些保證:
可是,promise最直接的好處就是鏈式調用。
經過現代的函數,咱們把回調附加到被返回的promise上代替以往的作法,造成一個promise chain:
doSomething().then(function(result) { return doSomethingElse(result); }) .then(function(newResult) { return doThirdThing(newResult); }) .then(function(finalResult) { console.log('Got the final result: ' + finalResult); }) .catch(failureCallback);
then裏的參數是可選的,catch(failureCallback)
是 then(null, failureCallback)
的縮略形式。以下所示,也能夠用 箭頭函數來表示:
doSomething() .then(result => doSomethingElse(result)) .then(newResult => doThirdThing(newResult)) .then(finalResult => { console.log(`Got the final result: ${finalResult}`); }) .catch(failureCallback);
注意:必定要返回promise,否則的話回調不會造成鏈式,錯誤也獲取不到(當省略{}時,箭頭函數將隱式返回)。
當異步代碼執行成功時,咱們纔會調用resolve(...), 當異步代碼失敗時就會調用reject(...)。
是