寰堝澶у叕鍙稿湪闈㈣瘯鐨勬椂鍊欏枩娆㈣闈㈣瘯瀹樻墜鍐欐壙璇猴紝鎵€浠ラ潰璇曟湁鏃跺€欐垜浠笉寰椾笉缂栫▼銆傚疄鐜拌嚜宸辩殑promise锛屽厛鏉ョ湅鐪嬪畼鏂筽romise鐨勭敤娉曪紝璇风湅涓嬮潰浠g爜锛歝onstfoo=()=>{returnnewPromise((resolve,reject)=>{setTimeout(()=>{resolve('111')},1000);})}foo().then((res)=>{console.log(res);})console.log('hello');//鍏堣緭鍑?hello'鐒跺悗杈撳嚭'111'棣栧厛锛屾垜浠牴鎹繖娈典唬鐮佹⒊鐞嗕竴涓嬫€濊矾锛氶鍏堝0鏄庝竴涓猚lass绫伙紝鎴戜滑绉颁箣涓篗yPromise锛汳yPromise绫绘帴鍙椾竴涓嚱鏁癴n浣滀负鍙傛暟锛宖n鏈変袱涓弬鏁皉esolve鍜宺eject锛岄兘鏄竴涓嚱鏁帮紱瀹氫箟MyPromise绫荤殑涓夌鐘舵€侊紝pending銆乫ulfilled鍜宺ejected锛汳yPromise绫荤殑鏋勯€犲嚱鏁板繀椤绘墽琛屽嚱鏁癴n锛屽皢resolve鍜宺eject浼犻€掔粰fn锛屽苟鍦ㄦ墽琛宺esolve鍜宺eject鏃舵敼鍙楳yPromise绫荤殑鐘舵€侊紱瀹炵幇then鏂规硶锛宼hen鏂规硶鎺ユ敹涓や釜鍑芥暟浣滀负鍙傛暟锛涘疄鐜伴摼寮忚皟鐢紱鎺ヤ笅鏉ワ紝璁╂垜浠敤浠g爜鏉ュ疄鐜板畠銆係tep1://瀹氫箟MyPromise鐨勪笁绉嶇姸鎬乧onstPENDING='pending';constFULFILLED='宸插畬鎴?;constREJECTED='鎷掔粷';classMyPromise{//绫荤殑灞炴€у彲浠ョ洿鎺ュ湪椤跺眰瀹氫箟status=PENDING;//鍒濆鐘舵€佽缃负pendingresult=undefined;//resolve浼犻€掔殑缁撴灉reason=undefined;//rejectconstructor(fn)浼犺繃鏉ョ殑缁撴灉{//瀹氫箟resolve鍑芥暟constresolve=(result)=>{//鍙湁褰損ending鐘舵€佹墠鑳藉彉涓篺ulfilled鐘舵€乮f(this.status===PENDING){//淇濆瓨缁撴灉骞跺悓鏃舵敼鍙樼姸鎬乼his.result=result;this.status=FULFILLED;}}//瀹氫箟鎷掔粷鍑芥暟constreject=(reason)=>{//鍙湁pending鐘舵€佹墠鑳芥敼鍙樹负rejected鐘舵€乮f(this.status===PENDING){//淇濆瓨缁撴灉骞舵敼鍙樼姸鎬佸悓鏃秚his.reason=rea鍎垮瓙;this.status=宸叉嫆缁濓紱}}//new鏃舵帴鏀跺埌鐨勫嚱鏁帮紝绔嬪嵆鎵цfn(resolve,reject);}}瑙i噴锛氬叾瀹炲氨鏄畾涔変簡涓€涓被锛岀劧鍚庡畾涔変簡涓€涓瀯閫犲嚱鏁帮紝鏋勯€犲嚱鏁版帴鍙椾竴涓嚱鏁帮紝绔嬪嵆鎵ц锛屽叾瀹炶繖涔熸槸new鎿嶄綔鐨勫熀鏈祦绋嬶紱绗簩姝ワ細//瀹氫箟MyPromise鐨勪笁绉嶇姸鎬乧onstPENDING='pending';constFULFILLED='宸插畬鎴?;constREJECTED='鎷掔粷';classMyPromise{//绫荤殑灞炴€у彲浠ョ洿鎺ュ湪椤跺眰瀹氫箟status=PENDING;//鍒濆鐘舵€佽缃负pendingresult=undefined;//resolve浼犻€掔殑鍊紃eason=undefined;//rejectconstructor(fn)浼犻€掔殑鍊納//瀹氫箟resolve鍑芥暟constresolve=(result)=>{//鍙湁pending鐘舵€佹墠鑳藉彉涓篺ulfilled鐘舵€乮f(this.status===PENDING){//淇濆瓨缁撴灉鐨勫悓鏃舵敼鍙樼姸鎬乼his.result=result;杩欍€傜姸鎬?宸插畬鎴愶紱}}//瀹氫箟鎷掔粷鍑芥暟constreject=(reason)=>{//鍙湁pending鐘舵€佸彲浠ユ洿鏀逛负rejected鐘舵€乮f(this.status===PENDING){//淇濆瓨缁撴灉鐨勫悓鏃舵敼鍙樼姸鎬乼his.reason=reason;this.status=宸叉嫆缁濓紱}}//绔嬪嵆鎵цnew鏃舵敹鍒扮殑鍑芥暟fn(resolve,reject);}//瀹氫箟then鏂规硶鎺ユ敹涓や釜鍑芥暟浣滀负鍙傛暟then(onResolve,onReject){//濡傛灉status婊¤冻鍒欐墽琛宱nResolve锛屽皢鎵цresolve鍑芥暟鏃朵繚瀛樼殑缁撴灉浼犻€掔粰if(this.status===FULFILLED){onResolve(this.result);}//濡傛灉鐘舵€佷负reject锛屽垯鎵цonReject锛屽皢鎵цreject鍑芥暟鏃跺瓨鍌ㄧ殑缁撴灉浼犻€掔粰if(this.status===REJECTED){onReject(this.reason)}}}瑙i噴锛氫笌绗竴姝ョ浉姣旓紝澧炲姞浜唗hen鏂规硶锛宼hen鏂规硶鍏跺疄寰堢畝鍗曘€傚畠鎺ュ彈涓や釜鍑芥暟骞舵墽琛屽畠浠€傝繖涓や釜鍑芥暟鐨勫弬鏁版槸绫荤殑result鍜宺eason灞炴€у€笺€傚叾瀹炲氨鏄痳esolve鍜宺eject鍑芥暟鎵ц鏃朵紶鍏ョ殑鍊笺€傝繖鏃跺€欙紝MyPromise鐨勫熀鏈姛鑳藉凡缁忓疄鐜颁簡锛堝紑蹇凁煒婏級锛屾垜浠潵璇曡瘯鐪嬶細constfoo=()=>{returnnewMyPromise((resolve,reject)=>{setTimeout(()=>{resolve('111')},1000);})}foo().then((res)=>{console.log(res);})console.log('hello');//杈撳嚭'hello'绛夌瓑瀵逛簡锛屽ソ鍍忔湁鐐逛笉瀵癸紒涓轰粈涔堝彧杈撳嚭'hello'鑰屼笉杈撳嚭'111'锛燄煒别煒别煒遍亣鍒颁簨鎯呬笉瑕佹厡寮狅紝鎴戜滑鍏堝洖椤句竴涓嬮€昏緫锛氫粠鏈€杩戠殑浠g爜鐗囨鍙互鐪嬪嚭锛宺esolve鍑芥暟鍦╯et涓湪Timeout涓紝寤惰繜1绉掓墽琛岋紝鐒跺悗鍚屾鎵цthen鏂规硶锛屽湪resolve鎵ц涔嬪墠銆傛鏃禡yPromise鐨勭姸鎬佽繕鏄?pending'锛屾墍浠nResolve鏂规硶鏍规湰娌℃湁鎵ц锛岃嚜鐒朵篃灏辨病鏈塸rint'111'锛涙壘鍒板師鍥犱簡锛岄偅鎴戜滑灏辨敼閫犱竴涓媡hen鏂规硶锛?/瀹氫箟MyPromise鐨勪笁绉嶇姸鎬乧onstPENDING='pending';constFULFILLED='宸插畬鎴?;constREJECTED='鎷掔粷';classMyPromise{//绫荤殑灞炴€у彲浠ョ洿鎺ュ湪椤跺眰瀹氫箟status=PENDING;//鍒濆鐘舵€佽缃负pendingresult=undefined;//resolve浼犻€掔殑鍊紃eason=undefined;//reject浼犻€掔殑鍊紀nResolveArr=[];//Storedthen鏂规硶鐨勭涓€涓弬鏁皁nResolve锛岀瓑寰呯姸鎬佹弧瓒冲悗鍐嶆墽琛岋紱onRejectArr=[];//瀛樺偍then鏂规硶onReject鐨勭浜屼釜鍙傛暟锛岀瓑寰呯姸鎬佸彉鎴恟ejected鍐嶆墽琛岋紱constructor(fn){//瀹氫箟瑙f瀽鍑芥暟constresolve=(result)=>{//鍙湁pending鐘舵€佹墠鑳藉彉涓篺ulfilled鐘舵€乮f(this.status===PENDING){//淇濆瓨缁撴灉骞跺悓鏃舵敼鍙樼姸鎬乼his.result=result;this.status=FULFILLED;//鎵цresolve鏃讹紝鎵цonResolveArr涓瓨鍌ㄧ殑鎵€鏈夊嚱鏁皌his.onResolveArr.map(onResolve=>onResolve());}}//瀹氫箟鎷掔粷鍑芥暟constreject=(reason)=>{//鍙湁pending鐘舵€佹墠鑳芥敼鍙樹负rejected鐘舵€乮f(this.status===PENDING){//淇濆瓨缁撴灉骞舵敼鍙樼姸鎬佸悓鏃秚his.reason=reason;this.status=宸叉嫆缁濓紱//鎵цreject鏃讹紝鎵цonRejectArr涓瓨鍌ㄧ殑鎵€鏈夊嚱鏁皌his.onRejectArr.map(onReject=>onReject());}}//鍑芥暟鎺ユ敹鍒皀ew鏃讹紝绔嬪嵆鎵цfn(resolve,reject);}//瀹氫箟then鏂规硶鎺ユ敹涓や釜鍑芥暟浣滀负鍙傛暟then(onResolve,onReject){//濡傛灉鐘舵€佷负pending锛屽垯灏唎nResolve鍜宱nReject鏆傚瓨鍒板搴旂殑鏁扮粍涓?/涓轰粈涔堬紵瀛樺偍鍦ㄦ暟缁勪腑锛熷洜涓簄ewMyPromise()鍙兘浼氳皟鐢ㄥ涓猼hen鏂规硶锛堟敞鎰忚繖涓嶆槸閾惧紡璋冪敤锛塱f(this.status===PENDING){//鍥犱负onResolve鍜宱nReject闇€瑕佹帴鍙楀弬鏁帮紝杩欓噷闇€瑕乸ush涓€涓尶鍚嶅嚱鏁?this.onResolveArr.push(()=>{onResolve(this.result);})this.onRejectArr.push(()=>{onReject(this.reason);})}//濡傛灉鐘舵€佹弧瓒筹紝鎵цonResolve,骞跺皢resolve鍑芥暟鎵ц鏃朵繚瀛樼殑缁撴灉浼犻€掔粰if(this.status===FULFILLED){onResolve(this.result);}//濡傛灉鐘舵€佷负rejected锛屽垯鎵цonReject锛屽皢鎵цreject鍑芥暟鏃朵繚瀛樼殑缁撴灉浼犲叆if(this.status===REJECTED){onReject(this.reason)}}}璇存槑锛氬浣犳墍鎰跨湅锛宼hen鏂规硶涓張澶氫簡涓€涓垽鏂€傚綋鐘舵€佷负pending鏃讹紝灏唎nResolve鍜宱nReject淇濆瓨鍒板搴旂殑鏁扮粍涓紝浠ヤ究浠ュ悗鎵цresolve鍜宺eject鏃舵墽琛岋紝绫讳技浜庤璁℃ā寮忎腑鐨勫彂甯冭闃呮ā寮忥紱杩欐椂then鏂规硶鍩烘湰瀹炵幇浜嗭紝鍐嶆墽琛屽垰鎵嶇殑渚嬪瓙锛屽彂鐜板彲浠ユ甯歌繑鍥?hello','111'浣嗭紒杩樹笉鑳介摼寮忚皟鐢煒傪煒傪煒傦紝鍥犱负鐜板湪then鏂规硶娌℃湁杩斿洖鍊硷紝鎵€浠ユ墽琛岀浜屼釜then鏂规硶鐨勬椂鍊欎細鎶ラ敊Cannotreadpropertiesofundefined銆傛帴涓嬫潵鎴戜滑缁х画瀹炵幇閾惧紡璋冪敤锛?/瀹氫箟MyPromise鐨勪笁绉嶇姸鎬乧onstPENDING='pending';constFULFILLED='宸插畬鎴?;constREJECTED='鎷掔粷';classMyPromise{//绫荤殑灞炴€у彲浠ョ洿鎺ュ湪椤跺眰瀹氫箟status=PENDING;//鍒濆鐘舵€佽缃负pendingresult=undefined;//resolve浼犻€掔殑鍊紃eason=undefined;//reject浼犻€掔殑鍊紀nResolveArr=[];//瀛樺偍then鏂规硶onResolve鐨勭涓€涓弬鏁帮紝褰撶姸鎬佸彉涓篺ulfill鏃舵墽琛岋紱onRejectArr=[];//瀛樺偍then鏂规硶onReject鐨勭浜屼釜鍙傛暟锛屽綋鐘舵€佸彉涓簉ejected鏃舵墽琛岋紱constructor(fn){//瀹氫箟resolve鍑芥暟constresolve=(result)=>{//鍙湁pending鐘舵€佹墠鑳藉彉涓篺ulfilled鐘舵€乮f(this.status===PENDING){//淇濆瓨缁撴灉骞跺悓鏃舵敼鍙樼姸鎬乼his.result=result;this.status=FULFILLED;//鎵цresolve鏃讹紝灏嗘墍鏈夊瓨鍌ㄥ湪onResolveArr涓殑鍑芥暟鍏ㄩ儴閲嶆柊鎵цthis.onResolveArr.map(onResolve=>onResolve());}}//瀹氫箟鎷掔粷鍑芥暟constreject=(reason)=>{//鍙湁pending鐘舵€佹墠鑳芥洿鏀逛负rejected鐘舵€乮f(this.status===PENDING){//淇濆瓨缁撴灉锛屽悓鏃舵洿鏀圭姸鎬乼his.reason=reason;this.status=宸叉嫆缁濓紱//鎵цreject鏃讹紝鎵цonRejectArr涓瓨鍌ㄧ殑鎵€鏈夊嚱鏁皌his.onRejectArr.map(onReject=>onReject());}}//绔嬪嵆鎵цnew鏃舵敹鍒扮殑鍑芥暟fn(resolve,reject);}//澶勭悊浣曟椂鎵ц绗簩涓猵romise鐨剅esolve鍜宺eject鍑芥暟handleNewPromise(res,newPromise,resolve,reject){//濡傛灉绗竴涓猼hen鍑芥暟杩斿洖鐨勫€兼槸褰撳墠鐨刾romise锛屽氨浼氬彂鐢熷惊鐜紩鐢╥f(res===newPromise){returnreject(newTypeError('Chainingcycledetectedforpromise'))}//闃叉澶氭璋冪敤letcalled;//濡傛灉鏄璞$被鍨嬫垨鑰呭嚱鏁扮被鍨媔f(typeofres==='object'||typeofres==='function'){//鑾峰彇绗竴涓猼hen鏂规硶杩斿洖鍊肩殑then灞炴€э紝濡傛灉鏄嚱鏁帮紝榛樿鏄痯romiseconstthen=res.then;//濡傛灉res鏄痯romise锛岄偅涔堢洿鎺ユ墽琛宼hen鏂规硶if(typeofthen==='function'){//浼犲叆this,newonResolve,newonRejectthen.call(res,newRes=>{//鎴愬姛鍜屽け璐ュ彧鑳借皟鐢ㄤ竴涓猧f(called)return;called=true;//閫掑綊璋冪敤handleNewPromiseuntilresisnotanobjectorfunctionthis.handleNewPromise(newRes,newPromise,resolve,reject);},newReason=>{//鎴愬姛鍜屽け璐ュ彧鑳借皟鐢ㄤ竴涓猧f(called)return;called=true;reject(newReason);})}else{瑙e喅(res);}}else{//濡傛灉鏄€肩被鍨嬶紝鐩存帴鎵ц绗簩涓猵romise鐨剅esolve鏂规硶锛岃繑鍥炵粨鏋滅粰resolve(res);}}//瀹氫箟then鏂规硶鎺ユ敹涓や釜鍑芥暟浣滀负鍙傛暟then(onResolve,onReject){//then鏂规硶杩斿洖涓€涓柊鐨刾romise鏂逛究閾惧紡璋冪敤constnewPromise=newMyPromise((resolve,reject)=>{//濡傛灉鐘舵€佹槸pending锛屾殏鏃舵斁鍦╫nResolve锛宱nReject瀛樺叆瀵瑰簲鐨勬暟缁?/涓轰粈涔堣淇濆瓨鍦ㄦ暟缁勪腑锛熷洜涓簄ewMyPromise()鍙兘浼氳皟鐢ㄥ涓猼hen鏂规硶锛堟敞鎰忚繖涓嶆槸閾惧紡璋冪敤锛塱f(this.status===PENDING){//鍥犱负onResolve鍜宱nReject闇€瑕佹帴鍙楀弬鏁帮紝杩欓噷闇€瑕乸ush涓€涓尶鍚嶅嚱鏁?this.onResolveArr.push(()=>{constresult=onResolve(this.result);this.handleNewPromise(result,newPromise,resolve,reject);})this.onRejectArr.push(()=>{constreason=onReject(this.reason);this.handleNewPromise(reason,newPromise,resolve,reject);})}//濡傛灉鐘舵€佹弧瓒筹紝鍒欐墽琛宱nResolve锛屽苟灏嗘墽琛宺esolve鍑芥暟鏃朵繚瀛樼殑缁撴灉浼犻€掔粰if(this.status===FULFILLED){constresult=onResolve(this.result);this.handleNewPromise(result,newPromise,resolve,reject);}//濡傛灉鐘舵€佷负rejected锛屽垯鎵цonReject锛屽皢鎵цreject鍑芥暟鏃跺瓨鍌ㄧ殑缁撴灉浼犻€掔粰if(this.status===REJECTED){const鍘熷洜=onReject(this.reason);this.handleNewPromise锛堝師鍥狅紝newPromise锛岃В鍐筹紝鎷掔粷锛夛紱}})杩斿洖鏂版壙璇猴紱}}瑙i噴锛歵hen鏂规硶杩斿洖涓€涓柊鐨刾romise锛屽鍔犱簡handleNewPromise鏂规硶锛屼富瑕佹槸鍒ゆ柇绗竴涓猼hen鍑芥暟鐨勮繑鍥炵粨鏋滐紝鐒跺悗鏍规嵁涓嶅悓鐨勭被鍨嬭繘琛岀浉搴旂殑鍏蜂綋鎿嶄綔銆傚叾瀹炰富瑕佹槸鍒ゆ柇绗竴涓猼hen鐨勮繑鍥炵粨鏋滄槸涓嶆槸promise銆傚鏋滄槸鐨勮瘽锛岃繖閲岄€掑綊璋冪敤handleNewPromise鏂规硶锛屽熀鏈疄鐜颁簡鑷繁鐨凱romise锛屽綋鐒惰繖杩樹笉瀹屾暣锛岃繕鏈変竴浜涢渶瑕佸吋瀹圭殑鍦版柟锛屽ぇ瀹舵湁浠€涔堟兂娉曞彲浠ュ湪璇勮閲岃璁哄尯~
