### è¨å½æ£ä¼ ï¼ä½ ç»åè¿ç»æåï¼  > 伿å¨ç¥ï¼jsæ¯å线ç¨å¼æ¥æºå¶çãè¿æ ·å°±ä¼å¯¼è´å¾å¤å¼æ¥å¤çä¼åµå¥å¾å¤çåè°å½æ°ï¼æä¸ºå¸¸è§çå°±æ¯ajax请æ±ï¼æä»¬éè¦ç请æ±ç»æè¿åååè¿è¡æäºæä½ãå¦ï¼ ```javascript function success(data, status) { console.log(data) } function fail(err, status) { console.log(err) } ajax({ url: myUrl, type: 'get', dataType: 'json', timeout: 1000, success: success(data, status), fail: fail(err, status) }) ``` > ä¹ä¸çè¿è¡åï¼ä¸å¤ç»æåï¼è®©ç»ææ¥çæ´ççä¸äºå§ï¼é£ä¹è¯æ³ä¸ä¸ï¼å¦æè¿æå¤ä¸ªè¯·æ±ä¾èµäºä¸ä¸ä¸ªè¯·æ±çè¿åå¼å¢ï¼äºä¸ªï¼å 个ï¼ä»£ç å°±ä¼åå¾é常åä½åä¸æç»´æ¤ãè¿ç§ç°è±¡ï¼æä»¬ä¸è¬äº²åå°ç§°å®ä¸ºâåè°å°ç±âãç°å¨è§£å³åè°å°ç±çææ®µæå¾å¤ï¼æ¯å¦é常æ¹ä¾¿çasync/awaitãPromiseçã > æä»¬ç°å¨è¦è®²çæ¯Promiseãå¨å¦ä»çå端é¢è¯ä¸ï¼Promiseç®ç´æ¯èç¹è¬çåå¨åï¼å个æä¹ä¸ªä¼é®ãé£ä¹æä»¬å¦ä½çæ£ç弿Promiseå¢ï¼ä¿è¯è¯´ç好ï¼âæ³è¦äºè§£å®ï¼å è¦æ¥è¿å®ï¼åæ ¢æ ¢å°å®ç°å®âãèªå·±å®ç°ä¸ä¸ªPromiseï¼ä¸å°±ä»ä¹é½æäºã  >å ¶å®ç½ç»ä¸å ³äºPromiseçæç« æå¾å¤ï¼æä¹æ¥é äºä¸äºç¸å ³æç« ï¼ææ«æç»åºç¸å ³åæé¾æ¥ãæä»¥æ¬æä¾§éç¹æ¯æå¨å®ç°Promiseè¿ç¨ä¸çæè·¯ä»¥å个人çä¸äºçè§£ï¼ææå ´è¶£çå°ä¼ä¼´å¯ä»¥ä¸èµ·äº¤æµã 妿ç¨promiseå®ç°ä¸é¢çajaxï¼å¤§æ¦æ¯è¿ä¸ªææï¼ ```javascript ajax().success().fail(); ``` ## ä½ä¸º Promise > é£ä¹ä»ä¹æ¯Promiseå¢ï¼ 1. Promiseæ¯ä¸ºäºè§£å³å¼æ¥ç¼ç¨çå¼ç«¯ï¼ä½¿ä½ çä»£ç æ´ææ¡çãæ´æ¸ æ°ãæ´æç»´æ¤ã 2. Promiseæ¯ä¸ä¸ªæé 彿°ï¼æè ç±»ï¼ï¼æ¥åä¸ä¸ªå½æ°ä½ä¸ºåæ°ï¼è¯¥å½æ°æ¥åresolveï¼rejectä¸¤ä¸ªåæ°ã 3. å®çå 鍿ä¸ç§ç¶æï¼pendingï¼è¿è¡ä¸ï¼ãfulfilledï¼å·²æåï¼årejectedï¼å·²å¤±è´¥ï¼ï¼å ¶ä¸pendingå¯ä»¥è½¬å为fulfilledæè årejectedï¼ä½æ¯ä¸è½éå转åï¼æåå失败ä¹ä¸è½ç¸äºè½¬åã 4. valueãreasonæåçåæ°å失败çé误信æ¯ã 5. thenæ¹æ³ï¼å®ç°é¾å¼è°ç¨ï¼ç±»ä¼¼äºjqã åºæ¬ç¨æ³ï¼ ```javascript let getInfo = new Promise((resolve, reject) => { setTimeout(_ => { let ran = Math.random(); console.log(ran); if (ran > 0.5) { resolve('success'); } else { reject('fail'); } }, 200); }); getInfo.then(r => { return r + ' ----> Vchat'; }).then(r => { console.log(r); }).catch(err => { console.log(err); }) // ran > 0.5è¾åº success ----> Vchat // ran <= 0.5è¾åº fail ``` å å®ä¸ªå°ç®æ ï¼ç¶å䏿¥æ¥å®ç°å®ã ## æå»ºPromise * åºç¡æé > é¦å éè¦äºè§£ä¸ä¸åºæ¬åçãæç¬¬ä¸æ¬¡æ¥è§¦Promiseçæ¶åï¼è¿å¾æµæï¼æè¸ï¼ãé£ä¼åªç¥éè¿ä¹åï¼ä¸ç¥éå°åºæ¯ä¸ªä»ä¹æµç¨èµ°åãä¸é¢ï¼æä»¬æ¥ççæåºæ¬çå®ç°ï¼ ```javascript function Promise(Fn){ let resolveCall = function() {console.log('ææ¯é»è®¤ç');}; // å®ä¹ä¸ºå½æ°æ¯ä¸ºäºé²æ¢æ²¡æthenæ¹æ³æ¶æ¥é this.then = (onFulfilled) => { resolveCall = onFulfilled; }; function resolve(v){ // å°resolveçåæ°ä¼ ç»thenä¸çåè° resolveCall(v); } Fn(resolve); } new Promise((resolve, reject) => { setTimeout(_ => { resolve('success'); }, 200) }).then(r => { console.log(r); }); // success ``` è¿ééè¦æ³¨æçæ¯ï¼å½æä»¬new Promise çæ¶åPromiseéç彿°ä¼ç´æ¥æ§è¡ãæä»¥å¦æä½ æ³å®ä¹ä¸ä¸ªPromiseä»¥å¾ åç¨ï¼æ¯å¦axioså°è£ ï¼éè¦ç¨å½æ°å è£ ãæ¯å¦è¿æ ·ï¼ ```javascript function myPromise() { return new Promise((resolve, reject) => { setTimeout(_ => { resolve('success'); }, 200) }) } // myPromise().then() ``` ååå°ä¸é¢ï¼å¨new Promise çæ¶åä¼ç«å³æ§è¡fnï¼éå°å¼æ¥æ¹æ³ï¼äºæ¯å æ§è¡thenä¸çæ¹æ³ï¼å° onFulfilled åå¨å° resolveCall ä¸ã弿¥æ¶é´å°äºåï¼æ§è¡ resolveï¼ä»èæ§è¡ resolveCallå³å¨åçthenæ¹æ³ãè¿æ¯è¾åºçæ¯æä»¬ä¼ å ¥çâsuccessâ > è¿é伿ä¸ä¸ªé®é¢ï¼å¦æ Promise æ¥åçæ¹æ³ä¸æ¯å¼æ¥çï¼åä¼å¯¼è´ resolve æ¯ then æ¹æ³å æ§è¡ãèæ¤æ¶ resolveCall è¿æ²¡æè¢«èµå¼ï¼å¾ä¸å°æä»¬æ³è¦çç»æãæä»¥è¦ç»resolveå ä¸å¼æ¥æä½ï¼ä»èä¿è¯thenæ¹æ³å æ§è¡ã ```javascript // ç´æ¥resolve new Promise((resolve, reject) => { resolve('success'); }).then(r => { console.log(r); // è¾åºä¸º âææ¯é»è®¤çâï¼å ä¸ºæ¤æ¶thenæ¹æ³è¿æ²¡æï¼thenæ¹æ³çåè°æ²¡æèµå¼ç»resolveCallï¼æ§è¡çæ¯é»è®¤å®ä¹çfunction() {}ã }); // å ä¸å¼æ¥å¤çï¼ä¿è¯thenæ¹æ³å æ§è¡ function resolve(v){ setTimeout(_ => { resolveCall(v); }) } ``` * å¢å é¾å¼è°ç¨ > é¾å¼è°ç¨æ¯Promiseé常éè¦çä¸ä¸ªç¹å¾ï¼ä½æ¯ä¸é¢åçé£ä¸ªå½æ°æ¾ç¶æ¯ä¸æ¯æé¾å¼è°ç¨çï¼æä»¥æä»¬éè¦è¿è¡å¤çï¼å¨æ¯ä¸ä¸ªthenæ¹æ³ä¸returnä¸ä¸thisã ```javascript function Promise(Fn){ this.resolves = []; // æ¹ä¾¿åå¨onFulfilled this.then = (onFulfilled) => { this.resolves.push(onFulfilled); return this; }; let resolve = (value) =>{ // æ¹ç¨ç®å¤´å½æ°ï¼è¿æ ·ä¸ç¨æ å¿thisæéé®é¢ setTimeout(_ => { this.resolves.forEach(fn => fn(value)); }); }; Fn(resolve); } ``` å¯ä»¥çå°ï¼è¿éå°æ¥æ¶thenåè°çæ¹æ³æ¹ä¸ºäºPromiseç屿§resolvesï¼è䏿¯æ°ç»ãè¿æ¯å ä¸ºå¦ææå¤ä¸ªthenï¼ä¾æ¬¡pushå°æ°ç»çæ¹å¼æè½åå¨ï¼å¦ååé¢çthenä¼å°ä¹åä¿åçè¦çæãè¿æ ·çå°resolve被è°ç¨çæ¶åï¼ä¾æ¬¡æ§è¡resolvesä¸ç彿°å°±å¯ä»¥äºãè¿æ ·å¯ä»¥è¿è¡ç®åçé¾å¼è°ç¨ã ```javascript new Promise((resolve, reject) => { resolve('success'); }).then(r => { console.log(r); // success }).then(r => { console.log(r); // success }); ``` 使¯æä»¬ä¼æè¿æ ·çéæ±, æä¸ä¸ªthen龿³èªå·±returnä¸ä¸ªåæ°ä¾åé¢çthen使ç¨ï¼å¦ï¼ ```javascript then(r => { console.log(r); return r + ' ---> Vchat'; }).then(); ``` è¦åå°è¿ä¸æ¥ï¼éè¦åå ä¸ä¸ªå¤çã ```javascript let resolve = (value) =>{ setTimeout(_ => { // æ¯æ¬¡æ§è¡thençåè°æ¶å¤æä¸ä¸æ¯å¦æè¿åå¼ï¼æçè¯æ´æ°value this.resolves.forEach(fn => value = fn(value) || value); }); }; ``` * å¢å ç¶æ > æä»¬å¨æç« å¼å§è¯´äºPromiseçä¸ç§ç¶æä»¥åæåå失败çåæ°ï¼ç°å¨æä»¬éè¦ä½ç°å¨èªå·±åçå®ä¾éé¢ã ```javascript function Promise(Fn){ this.resolves = []; this.status = 'PENDING'; // åå§ä¸º'PENDING'ç¶æ this.value; this.then = (onFulfilled) => { if (this.status === 'PENDING') { // 妿æ¯'PENDING'ï¼åå¨åå°æ°ç»ä¸ this.resolves.push(onFulfilled); } else if (this.status === 'FULFILLED') { // 妿æ¯'FULFILLED'ï¼åç«å³æ§è¡åè° console.log('isFULFILLED'); onFulfilled(this.value); } return this; }; let resolve = (value) =>{ if (this.status === 'PENDING') { // 'PENDING' ç¶æææ§è¡resolveæä½ setTimeout(_ => { //ç¶æè½¬æ¢ä¸ºFULFILLED //æ§è¡thenæ¶ä¿åå°resolveséçåè° //妿åè°æè¿åå¼ï¼æ´æ°å½åvalue this.status = 'FULFILLED'; this.resolves.forEach(fn => value = fn(value) || value); // è¿éæä¸ä¸ªé®é¢ å®é ä¸Promise 并没æå¤ææ¯å¦æfanhuiè¿åå¼ // fn => value = fn(value)ï¼æ²¡æè¿åå¼å°±æ¯ undefined this.value = value; }); } }; Fn(resolve); } ``` è¿éå¯è½ä¼æåå¦è§å¾å°æï¼æä»¬éè¿ä¸ä¸ªä¾åæ¥è¯´æå¢å çè¿äºå¤çå°åºæä»ä¹ç¨ã ```javascript let getInfo = new Promise((resolve, reject) => { resolve('success'); }).then(_ => { console.log('hahah'); }); setTimeout(_ => { getInfo.then(r => { console.log(r); // success }) }, 200); ``` å¨resolve彿°ä¸ï¼å¤æäº'PENDING' ç¶æææ§è¡setTimeoutæ¹æ³ï¼å¹¶ä¸å¨æ§è¡æ¶æ´æ¹äºç¶æä¸º'FULFILLED'ãè¿æ¶ï¼å¦æè¿è¡è¿ä¸ªä¾åï¼åªä¼è¾åºä¸ä¸ªâhahahâï¼å 为æ¥ä¸æ¥ç弿¥æ¹æ³è°ç¨æ¶ç¶æå·²ç»è¢«æ¹ä¸ºâFULFILLEDâï¼æä»¥ä¸ä¼å次æ§è¡ã è¿ç§æ åµè¦æ³å®å¯ä»¥æ§è¡ï¼å°±éè¦ç¨å°thenæ¹æ³éç夿ï¼å¦æç¶ææ¯'FULFILLED'ï¼åç«å³æ§è¡åè°ãæ¤æ¶çä¼ åæ¯å¨resolveæ§è¡æ¶ä¿åçthis.valueãè¿æ ·å°±ç¬¦åPromiseçç¶æååï¼PENDINGä¸å¯éï¼FULFILLEDåREJECTEDä¸è½ç¸äºè½¬åã * å¢å 失败å¤ç >å¯è½æåå¦åç°æä¸ç´æ²¡æå¤çrejectï¼ä¸ç¨çæ¥ãrejectåresolveæµç¨æ¯ä¸æ ·çï¼éè¦ä¸ä¸ªreasonå为失败çä¿¡æ¯è¿åãå¨é¾å¼è°ç¨ä¸ï¼åªè¦æä¸å¤åºç°äºrejectï¼åç»çresolveé½ä¸åºè¯¥æ§è¡ï¼èæ¯ç´æ¥è¿årejectã ```javascript this.reason; this.rejects = []; // æ¥æ¶å¤±è´¥çonRejected彿° if (this.status === 'PENDING') { this.rejects.push(onRejected); } // å¦æç¶ææ¯'REJECTED'ï¼åç«å³æ§è¡onRejectedã if (this.status === 'REJECTED') { onRejected(this.reason); } // rejectæ¹æ³ let reject = (reason) =>{ if (this.status === 'PENDING') { setTimeout(_ => { //ç¶æè½¬æ¢ä¸ºREJECTED //æ§è¡thenæ¶ä¿åå°rejectséçåè° //妿åè°æè¿åå¼ï¼æ´æ°å½åreason this.status = 'REJECTED'; this.rejects.forEach(fn => reason = fn(reason) || reason); this.reason = reason; }); } }; // æ§è¡Fnåºéç´æ¥reject try { Fn(resolve, reject); } catch(err) { reject(err); } ``` 卿§è¡å¨åthenä¸çåè°å½æ°é£ä¸æ¥æä¸ä¸ªç»èä¸ç´æ²¡æå¤çï¼é£å°±æ¯å¤ææ¯å¦æonFulfilledæè onRejectedæ¹æ³ï¼å 为æ¯å 许ä¸è¦å ¶ä¸ä¸ä¸ªçãç°å¨å¦æthenä¸ç¼ºå°æä¸ªåè°ï¼ä¼ç´æ¥pushè¿undefinedï¼å¦ææ§è¡çè¯å°±ä¼åºéï¼æä»¥è¦å 夿ä¸ä¸æ¯å¦æ¯å½æ°ã ```javascript this.then = (onFulfilled, onRejected) => { // 夿æ¯å¦æ¯å½æ°ï¼æ¯å½æ°åæ§è¡ function success (value) { return typeof onFulfilled === 'function' && onFulfilled(value) || value; } function erro (reason) { return typeof onRejected === 'function' && onRejected(reason) || reason; } // ä¸é¢çå¤çä¹è¦æ¢ææ°å®ä¹ç彿° if (this.status === 'PENDING') { this.resolves.push(success); this.rejects.push(erro); } else if (this.status === 'FULFILLED') { success(this.value); } else if (this.status === 'REJECTED') { erro(this.reason); } return this; }; ``` å 为rejectåè°æ§è¡æ¶åresolveåºæ¬ä¸æ ·ï¼æä»¥ç¨å¾®ä¼åä¸ä¸é¨å代ç ã ```javascript if(this.status === 'PENDING') { let transition = (status, val) => { setTimeout(_ => { this.status = status; let f = status === 'FULFILLED', queue = this[f ? 'resolves' : 'rejects']; queue.forEach(fn => val = fn(val) || val); this[f ? 'value' : 'reason'] = val; }); }; function resolve(value) { transition('FULFILLED', value); } function reject(reason) { transition('REJECTED', reason); } } ``` * ä¸²è¡ Promise > å设æå¤ä¸ªajax请æ±ä¸²èè°ç¨ï¼å³ä¸ä¸ä¸ªéè¦ä¸ä¸ä¸ªçè¿åå¼ä½ä¸ºåæ°ï¼å¹¶ä¸è¦returnä¸ä¸ªæ°çPromiseææé误ãè¿æ ·æä»¬ç°å¨ç忳就ä¸è½å®ç°äºã >æççè§£æ¯ä¹åçthenè¿åçä¸ç´æ¯thisï¼ä½æ¯å¦ææä¸ä¸ªthenæ¹æ³åºéäºï¼å°±æ æ³è·³åºå¾ªç¯ãæåºå¼å¸¸ãèä¸ååä¸ä¸ä¸ªPromiseï¼åªè¦ç¶ææ¹åæâFULFILLEDâæè âREJECTEDâå°±ä¸å è®¸åæ¬¡æ¹åã >ä¹åçä¾åå¯ä»¥æ§è¡æ¯å 为没æå¨thenä¸åå¼å¸¸çå¤çï¼å³æ²¡ærejectï¼åªæ¯ä¼ éäºæ°æ®ãæä»¥å¦æè¦åå°æ¯ä¸æ¥é½å¯ä»¥ç¬ç«çæåºå¼å¸¸ï¼ä»èç»æ¢åé¢çæ¹æ³æ§è¡ï¼è¿éè¦å次æ¹é ï¼æä»¬éè¦æ¯ä¸ªthenæ¹æ³ä¸returnä¸ä¸ªæ°çPromiseã ```javascript // æthenæ¹æ³æ¾å°ååä¸ï¼è¿æ ·å¨newä¸ä¸ªæ°çPromiseæ¶ä¼å»å¼ç¨prototypeçthenæ¹æ³ï¼è䏿¯åå¤å¶ä¸ä»½ã Promise.prototype.then = function(onFulfilled, onRejected) { let promise = this; return new Promise((resolve, reject) => { function success (value) { let val = typeof onFulfilled === 'function' && onFulfilled(value) || value; resolve(val); // æ§è¡å®è¿ä¸ªthenæ¹æ³çonFulfilled以åï¼resolveä¸ä¸ä¸ªthenæ¹æ³ } function erro (reason) { let rea = typeof onRejected === 'function' && onRejected(reason) || reason; reject(rea); // åresolve } if (promise.status === 'PENDING') { promise.resolves.push(success); promise.rejects.push(erro); } else if (promise.status === 'FULFILLED') { success(promise.value); } else if (promise.status === 'REJECTED') { erro(promise.reason); } }); }; ``` 卿åç彿°ä¸è¿éè¦åä¸ä¸ªå¤çï¼ç¨ä»¥æ¯æå¨thençåè°å½æ°ï¼onFulfilledï¼ä¸returnçPromiseã妿onFulfilledæ¹æ³returnçæ¯ä¸ä¸ªPromiseï¼åç´æ¥æ§è¡å®çthenæ¹æ³ã妿æåäºï¼å°±ç»§ç»æ§è¡åé¢çthené¾ï¼å¤±è´¥äºç´æ¥è°ç¨rejectã ```javascript function success(value) { let val = typeof onFulfilled === 'function' && onFulfilled(value) || value; if(val && typeof val['then'] === 'function'){ // 夿æ¯å¦æthenæ¹æ³ val.then(function(value){ // 妿è¿åçæ¯Promise åç´æ¥æ§è¡å¾å°ç»æååè°ç¨åé¢çthenæ¹æ³ resolve(value); },function(reason){ reject(reason); }); }else{ resolve(val); } } ``` æ¾ä¸ªä¾åæµè¯ä¸ä¸ ```javascript function getInfo(success, fail) { return new Promise((resolve, reject) => { setTimeout(_ => { let ran = Math.random(); console.log(success, ran); if (ran > 0.5) { resolve(success); } else { reject(fail); } }, 200); }) } getInfo('Vchat', 'fail').then(res => { console.log(res); return getInfo('å¯ä»¥çº¿ä¸é¢è§äº', 'erro'); }, rej => { console.log(rej); }).then(res => { console.log(res); }, rej => { console.log(rej); }); // è¾åº // Vchat 0.8914818954810422 // Vchat // å¯ä»¥çº¿ä¸é¢è§äº 0.03702367800412443 // erro ``` ## æ»ç» > å°è¿éï¼Promiseç主è¦åè½åºæ¬ä¸é½å®ç°äºãè¿æå¾å¤å®ç¨çæ©å±ï¼æä»¬ä¹å¯ä»¥æ·»å ã æ¯å¦ catchå¯ä»¥çåthençä¸ä¸ªè¯æ³ç³ï¼åªæonRejectedåè°çthenæ¹æ³ãå ¶å®Promiseçæ¹æ³ï¼æ¯å¦.allã.race ççï¼æå ´è¶£çå°ä¼ä¼´å¯ä»¥èªå·±å®ç°ä¸ä¸ãå¦å¤ï¼æä¸å¦æä¸å¯¹ä¹å¤ï¼è¿è¯·æåºã ```javascript Promise.prototype.catch = function(onRejected){ return this.then(null, onRejected); } ``` ## ç¸å ³æç« * [ææææä½ å®ç°ä¸ä¸ªå®æ´ç Promise](http://www.cnblogs.com/huansky/p/6064402.html) * [æä½ 䏿¥ä¸æ¥å®ç°ä¸ä¸ªPromise - é£é](https://www.tuicool.com/articles/RzQRV3) * [é®ä¸å³°èå¸çes6-Promiseç« è](http://es6.ruanyifeng.com/#docs/promise) ## 交æµç¾¤ > qqå端交æµç¾¤ï¼960807765ï¼æ¬¢è¿åç§ææ¯äº¤æµï¼æå¾ ä½ çå å ¥ ## å ¬ä¼å· 欢è¿å ³æ³¨å ¬ä¼å· **å端å卿º**ï¼æ±ä¸ç¯çå端äºä¸äºï¼ä¸æ³¨ææ¯ï¼ä¹ä¼æ¶å¸¸è¿·ç³ã叿卿ªæ¥çå端路ä¸ï¼ä¸ä½ ä¸åæé¿ã 