const RESOLVE = 'resolved';const REJECT = 'rejected';const PENDING = 'pending';const handlePromise = (result,newPromise,resolve,reject) => { if(result === newPromise){ throw new Error("can't not return oneself") } if((typeof result === 'object' && typeof result !== null) || typeof result === 'function'){ let lock = false try { const then = result.then; if(typeof then === 'function'){ then.call(result,(r)=>{ if(lock) return ; handlePromise(r,newPromise,resolve,reject); lock = true },(e)=>{ if(lock) return ; reject(e); lock = true; }) }else{ resolve(result) } } catch(error){ reject(error) } }else{ resolve(result) }}class JJPromise { status = PENDING; result = undefined; reason = undefined; onResolveArr = []; onRejectArr = []; constructor(excution){ const resolve = (result) => { if(this.status === PENDING){ this.result = result; this.status = RESOLVE; this.onResolveArr.map((fn) => fn()) } } const reject = (reason) => { if(this.status === PENDING){ this.reason = reason; this.status = REJECT; this.onRejectArr.map((fn) => fn()) } } try { excution(resolve,reject) } catch(error) { reject(error); } } then(onResolved,onRejected){ onResolved = typeof onResolved === 'function' ? onResolved : (data) => data; onRejected = typeof onRejected === 'function' ? onRejected : (err) => { throw new Error(err) } const newPromise = new JJPromise((resolve,reject) => { if(this.status === RESOLVE){ setTimeout(() => { try { const result = onResolved(this.result) handlePromise(result,newPromise,resolve,reject); } catch(error) { reject(error) } },0) } if(this.status === REJECT){ setTimeout(() => { try { const result = onRejected(this.reason) handlePromise(result,newPromise,resolve,reject); } catch(error) { reject(error) } },0) } if(this.status === PENDING){ this.onResolveArr.push(()=>{ try { const result = onResolved(this.result) handlePromise(result,newPromise,resolve,reject); } catch(error) { reject(error) } }) this.onRejectArr.push(()=>{ try { const result = onRejected(this.result) handlePromise(result,newPromise,resolve,reject); } catch(error) { reject(error) } }) } }) return newPromise; } catch(onRejected){ return this.then(undefined,onRejected); }}const test = new JJPromise((resolve,reject) => { resolve('123')})test.then((res) => {console.log(res)})console.log('1')// 1// 123