1. const RESOLVE = 'resolved';
    2. const REJECT = 'rejected';
    3. const PENDING = 'pending';
    4. const handlePromise = (result,newPromise,resolve,reject) => {
    5. if(result === newPromise){
    6. throw new Error("can't not return oneself")
    7. }
    8. if((typeof result === 'object' && typeof result !== null) || typeof result === 'function'){
    9. let lock = false
    10. try {
    11. const then = result.then;
    12. if(typeof then === 'function'){
    13. then.call(result,(r)=>{
    14. if(lock) return ;
    15. handlePromise(r,newPromise,resolve,reject);
    16. lock = true
    17. },(e)=>{
    18. if(lock) return ;
    19. reject(e);
    20. lock = true;
    21. })
    22. }else{
    23. resolve(result)
    24. }
    25. } catch(error){
    26. reject(error)
    27. }
    28. }else{
    29. resolve(result)
    30. }
    31. }
    32. class JJPromise {
    33. status = PENDING;
    34. result = undefined;
    35. reason = undefined;
    36. onResolveArr = [];
    37. onRejectArr = [];
    38. constructor(excution){
    39. const resolve = (result) => {
    40. if(this.status === PENDING){
    41. this.result = result;
    42. this.status = RESOLVE;
    43. this.onResolveArr.map((fn) => fn())
    44. }
    45. }
    46. const reject = (reason) => {
    47. if(this.status === PENDING){
    48. this.reason = reason;
    49. this.status = REJECT;
    50. this.onRejectArr.map((fn) => fn())
    51. }
    52. }
    53. try {
    54. excution(resolve,reject)
    55. } catch(error) {
    56. reject(error);
    57. }
    58. }
    59. then(onResolved,onRejected){
    60. onResolved = typeof onResolved === 'function' ? onResolved : (data) => data;
    61. onRejected = typeof onRejected === 'function' ? onRejected : (err) => {
    62. throw new Error(err)
    63. }
    64. const newPromise = new JJPromise((resolve,reject) => {
    65. if(this.status === RESOLVE){
    66. setTimeout(() => {
    67. try {
    68. const result = onResolved(this.result)
    69. handlePromise(result,newPromise,resolve,reject);
    70. } catch(error) {
    71. reject(error)
    72. }
    73. },0)
    74. }
    75. if(this.status === REJECT){
    76. setTimeout(() => {
    77. try {
    78. const result = onRejected(this.reason)
    79. handlePromise(result,newPromise,resolve,reject);
    80. } catch(error) {
    81. reject(error)
    82. }
    83. },0)
    84. }
    85. if(this.status === PENDING){
    86. this.onResolveArr.push(()=>{
    87. try {
    88. const result = onResolved(this.result)
    89. handlePromise(result,newPromise,resolve,reject);
    90. } catch(error) {
    91. reject(error)
    92. }
    93. })
    94. this.onRejectArr.push(()=>{
    95. try {
    96. const result = onRejected(this.result)
    97. handlePromise(result,newPromise,resolve,reject);
    98. } catch(error) {
    99. reject(error)
    100. }
    101. })
    102. }
    103. })
    104. return newPromise;
    105. }
    106. catch(onRejected){
    107. return this.then(undefined,onRejected);
    108. }
    109. }
    110. const test = new JJPromise((resolve,reject) => {
    111. resolve('123')
    112. })
    113. test.then((res) => {console.log(res)})
    114. console.log('1')
    115. // 1
    116. // 123