37.promise讲解

2021-11-26  本文已影响0人  静昕妈妈芦培培

在promise出现之前,对异步请求的处理方式如下

function requestData(url, successCallback, failureCallback) {
  // 模拟异步请求
  setTimeout(() => {
    if (url === "coderwhy") {
      //请求成功
      const names = ["lily", "koby"];
      successCallback(names);
    } else {
      const errMsg = "请求失败";
      failureCallback(errMsg);
    }
  }, 2000);
}

requestData(
  "coderwhy",
  (res) => {
    console.log("请求成功的结果是", res);
  },
  (err) => {
    console.log("请求失败的结果是", err);
  }
);

执行结果:

请求成功的结果是 [ 'lily', 'koby' ]

什么是promise和基本使用

Promise是一个类,可以翻译成承诺、许诺、期约

下面是简写Promise类的基本使用的实现过程,用HyPromise这个自定义类表现

class HyPromise {
  constructor(executor) {
    this.fulfilledFns = [];
    this.rejectedFns = [];
    //创建对象时,executor函数会被立即执行,并需要传入resolve,reject两个回调函数
    const resolve = function (res) {
      // resolve函数执行,会立马执行通过执行then方法,传入的fulfilled函数
      this.fulfilledFns.forEach((fn) => {
        // resolve执行时,接收的参数,会作为通过执行then方法传入的fulfilled函数的参数传入
        fn(res);
      });
    };
    const reject = function (err) {
      // reject函数执行,会立马执行通过执行then方法,传入的rejected函数
      this.rejectedFns.forEach((fn) => {
        // reject执行时,接收的参数,会作为通过执行then方法传入的rejected函数的参数传入
        fn(err);
      });
    };
    executor(resolve, reject);
  }

  //给 HyPromise.prototype对象上添加一个then方法, 可以被所有的HyPromise对象调用
  // then方法接受两个回调函数
  then(fulfilled, rejected) {
    //把通过执行then传入的回调存起来,以便resolve和reject回调函数执行的时候调用
    this.fulfilledFns.push(fulfilled);
    this.rejectedFns.push(rejected);
  }
}

下面是promise的基本使用


// 创建一个Promise对象
const promise = new Promise((resolve, reject) => {
  // 模拟异步请求
  setTimeout(() => {
    //请求成功
    resolve("请求结果");
    //请求失败
    // reject('失败原因')
  }, 3000);
});

promise.then(
  (res) => {
    console.log(res);
  },
  (err) => {
    console.log(err);
  }
);

// 可以多次执行promise对象的then函数,注册多个fulfilled和rejected函数
promise.then(
  (res) => {
    console.log(res);
  },
  (err) => {
    console.log(err);
  }
);


使用promise对异步请求的处理方式如下

//
function requestData(url) {
  return new Promise((resolve, reject) => {
    // 模拟异步请求
    setTimeout(() => {
      if (url === "coderwhy") {
        //请求成功
        const names = ["lily", "koby"];
        resolve(names);
      } else {
        const errMsg = "请求失败";
        reject(errMsg);
      }
    }, 2000);
  });
}

const promise = requestData("coderwhy");
promise.then(
  (res) => {
    console.log("请求成功的结果是", res);
  },
  (err) => {
    console.log("请求失败的结果是", err);
  }
);

promise对象的状态

promise对象有三种状态:



// 创建一个Promise对象
const promise = new Promise((resolve, reject) => {
  // 此时promise对象的状态为pending

  // 模拟异步请求
  setTimeout(() => {
    //请求成功:resolve函数的执行,把promise对象的状态修改为fulfilled
    resolve("请求结果");

    resolve(
      "promise对象的状态一旦被敲定,并不能再被修改,再次执行resolve或reject函数,什么效果都没有"
    );

    console.log(
      "执行resolve函数,promise对象的状态被敲定,并不影响下面代码的执行"
    );
    //请求失败:reject函数的执行,把promise对象的状态修改为rejected
    // reject('失败原因')
  }, 3000);
});

promise.then(
  (res) => {
    // 此时,promise对象的状态已经改为fulfilled
    console.log(res);
  },
  (err) => {
    // 此时,promise对象的状态已经改为rejected
    console.log(err);
  }
);

执行结果:

执行resolve函数,promise对象的状态被敲定,并不影响下面代码的执行
请求结果

promise的resolve回调的参数

promise的resolve回调函数的参数

// resolve参数为一个普通的值或对象
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve({ name: "why", age: 18 });
  });
});
promise.then(
  (res) => {
    console.log(res);
  },
  (err) => {
    console.log(err);
  }
);
// 执行结果:{ name: 'why', age: 18 }
// resolve参数为一个新的promise对象
const newPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(111);
  });
});
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(newPromise);
  });
});
promise1.then(
  (res) => {
    console.log(res);
  },
  (err) => {
    console.log(err);
  }
);
// 执行结果:111
// resolve参数为一个实现了then方法的对象
const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve({
      then(resolve, reject) {
        //then方法会立即被执行
        resolve("then");
      },
    });
  });
});
promise2.then(
  (res) => {
    console.log(res);
  },
  (err) => {
    console.log(err);
  }
);
// 执行结果:then


promise的then方法

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve({ name: "why", age: 18 });
  });
});

//promise.then方法执行返回一个promise对象
//resolved函数执行染回一个普通的值或对象,这个值会作为thenPromise对象的resolve函数的参数传进去
const thenPromise = promise.then(
  (res) => {
    return "aaa";
  },
  (err) => {}
);

thenPromise.then(
  (res) => {
    console.log(res);
  },
  (err) => {}
);

//执行结果:aaa

//resolved函数执行染回一个新的promise对象newPromise,这个值会作为thenPromise对象的resolve函数的参数传进去
//thenPromise对象的状态由这个新对象newPromise决定
const newPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve({ name: "why", age: 18 });
  });
});
const thenPromise1 = promise.then(
  (res) => {
    return newPromise;
  },
  (err) => {}
);

thenPromise1.then(
  (res) => {
    console.log(res);
  },
  (err) => {}
);

//执行结果:{ name: "why", age: 18 }

//resolved函数执行返回一个实现了then方法的对象,这个对象的then方法会立即被执行,
//then方法中执行了resolve,则thenPromise对象的状态变为fulfilled,
//then方法中执行了reject,则thenPromise对象的状态变为rejected,

const thenPromise2 = promise.then(
  (res) => {
    return {
      then(resolve, reject) {
        resolve("then");
      },
    };
  },
  (err) => {}
);

thenPromise2.then(
  (res) => {
    console.log(res);
  },
  (err) => {}
);

//执行结果:then

//promise的状态变为了fulfilled,执行了fulfilled函数,fulfilled函数执行过程中抛出异常,
//则promise.then方法返回的promise对象thenPromise3状态变成了rejected,则执行thenPromise3的rejected的回调函数
const thenPromise3 = promise.then(
  (res) => {
    throw new Promise("fulfilled函数执行报错了");
  },
  (err) => {}
);

thenPromise3.then(
  (res) => {
    console.log(res);
  },
  (err) => {
    console.log(err);
  }
);

// TypeError: Promise resolver fulfilled函数执行报错了 is not a function
//     at new Promise (<anonymous>)
//     at G:\03.教学视频\0.javascript-王红元\js高级\code\16.promise\6.promise对象的then方法.js:167:11

如果promise对象执行了reject回调,状态变为rejected,执行rejected函数,此时promise对象的then返回的thenPromise对象的状态怎么决定呢?

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("报错了啊啊啊");
  });
});
const thenPromise4 = promise1.then(
  (res) => {
    // console.log(res);
  },
  (err) => {
    return 888;
  }
);

thenPromise4.then(
  (res) => {
    console.log(999, res);
  },
  (err) => {
    console.log(err);
  }
);

//999 888

const thenPromise5 = promise1.then(
  (res) => {
    // console.log(res);
  },
  (err) => {
    throw new Error("竟然报错了");
  }
);

thenPromise5.then(
  (res) => {
    console.log(999, res);
  },
  (err) => {
    console.log(1000, err);
  }
);
// 1000 Error: 竟然报错了
//     at G:\03.教学视频\0.javascript-王红元\js高级\code\16.promise\6.promise对象的then方法.js:225:11

promise对象的catch方法

promise对象的rejected回调

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("msg error");
  });
});

promise.then(
  (res) => {
    return "aaa";
  },
  (err) => {
    console.log(err);
  }
);

//执行结果:msg error

//当executor函数执行过程中抛出异常,当前promise的状态会变为rejected,rejected回调被调用,异常信息会作为rejected的参数传入
const promise1 = new Promise((resolve, reject) => {
  throw new Error("错误信息");
});

promise1.then(
  (res) => {
    return "aaa";
  },
  (err) => {
    console.log(err);
  }
);

// 执行结果:
// Error: 错误信息
//     at G:\03.教学视频\0.javascript-王红元\js高级\code\16.promise\7.promise对象的catch方法.js:25:9
//     at new Promise (<anonymous>)
//     at Object.<anonymous> (G:\03.教学视频\0.javascript-王红元\js高级\code\16.promise\7.promise对象的catch方法.js:24:18)


catch方法

promise1.then(undefined, (err) => {
  console.log(err);
});

上面代码可以简写为如下:

promise1.catch((err) => {
  console.log(err);
});

catch的特殊性

const promise1 = new Promise((resolve, reject) => {
  throw new Error("错误信息");
});
// 1.下面代码,promise1的executor函数执行过程中抛出了异常,promise1.then方法中没有注册rejected回调函数,则执行catch的回调函数
promise1
  .then((res) => {
    console.log(res);
  })
  .catch((err) => {
    console.log(err);
  });
// Error: 错误信息
// at G:\03.教学视频\0.javascript-王红元\js高级\code\16.promise\7.promise对象的catch方法.js:25:9
// at new Promise (<anonymous>)
// at Object.<anonymous> (G:\03.教学视频\0.javascript-王红元\js高级\code\16.promise\7.promise对象的catch方法.js:24:18)


//下面代码,promise2的状态变为了fulfilled,执行了fulfilled函数,
//fulfilled函数中返回的promise对象状态变为了rejected,则promise2.then方法返回的promise对象状态也变成了rejected,则执行catch的回调函数
const promise2 = new Promise((resolve, reject) => {
  resolve(111);
});
promise2
  .then((res) => {
    return new Promise((resolve, reject) => {
      reject("报错了");
    });
  })
  .catch((err) => {
    console.log(err);
  });

拒绝捕获问题

const promise4 = new Promise((resolve, reject) => {
  reject("报错了啊啊啊");
});
promise4.then((res) => {
  console.log(res);
});
promise4.catch((err) => {
  console.log(err);
});

Unhandled promise rejection.关于这个报错问题,意思是没有拒绝捕获回调。应该改为下面

const promise5 = new Promise((resolve, reject) => {
  reject("报错了啊啊啊");
});
promise5
  .then((res) => {
    console.log(res);
  })
  .catch((err) => {
    console.log(err);
  });
promise5.catch((err) => {
  console.log(err);
});

promise对象的finally方法

const promise2 = new Promise((resolve, reject) => {
 resolve(111);
});
promise2
 .then((res) => {
   console.log(res)
 })
 .catch((err) => {
   console.log(err);
 })
 .finally(() => {
   console.log('promise的状态被改变了')
 });

// 111
// promise的状态被改变了

Promise类方法-resolve

Promise.resolve的传参处理,遵循promise对象的resolve传参处理

//封装一个方法,可以把一个值转换为promise对象
function toPromise(val) {
  return new Promise((resolve, reject) => {
    resolve(val);
  });
}
const objPromise = toPromise({ name: "lily", age: 18 });

const promise = Promise.resolve(111);
//相当于
const promise1 = new Promise((resolve, reject) => {
  resolve(111);
});

Promise类方法-reject

Promise.reject的参数不管是什么类型,都原样传给promise的rejected

const promise = Promise.reject({ name: "lily" });
//相当于
const promise1 = new Promise((resolve, reject) => {
  reject({ name: "lily" });
});

//下面为了解决没有捕获拒绝回调的报错
promise.catch((err) => {});
promise1.catch((err) => {});

//Promise.reject的参数不管是什么类型,都原样传给promise的rejected
const promise3 = new Promise((resolve, reject) => {
  resolve(111)
});
const promise2 = Promise.reject(promise3);
promise2
  .then((res) => {
    console.log(res); 
  })
  .catch((err) => {
    console.log(err);
  });
// Promise { 111 }  promise对象被原样输出了

Promise类的all方法

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(111);
  }, 100);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(222);
  }, 200);
});

const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(333);
  }, 300);
});

const promise4 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("error msg");
  }, 300);
});
const promise5 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("error error");
  }, 300);
});

const allPromise = Promise.all([promise1, promise2, promise3]);
allPromise
  .then((res) => {
    console.log(res);
  })
  .catch((err) => {
    console.log(err);
  });

// [ 111, 222, 333 ]

const allPromise1 = Promise.all([promise1, promise4, promise5]);
allPromise1
  .then((res) => {
    console.log(res);
  })
  .catch((err) => {
    console.log(err);
  });

// error msg

Promise类的allSettled方法



const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(111);
  }, 100);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(222);
  }, 200);
});

const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("error msg");
  }, 300);
});
const promise4 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("error error");
  }, 400);
});

const promise = Promise.allSettled([promise1, promise2, promise3, promise4]);
promise.then((res) => {
  console.log(res);
})

// [
//   { status: 'fulfilled', value: 111 },
//   { status: 'fulfilled', value: 222 },
//   { status: 'rejected', reason: 'error msg' },
//   { status: 'rejected', reason: 'error error' }
// ]

Promise类的race方法

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(111);
  }, 100);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(222);
  }, 200);
});

const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("error msg");
  }, 300);
});
const promise4 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("error error");
  }, 400);
});

const promise = Promise.race([promise1, promise2, promise3, promise4]);
promise
  .then((res) => {
    console.log("res", res);
  })
  .catch((err) => {
    console.log("err", err);
  });

//err 111
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(111);
  }, 100);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(222);
  }, 200);
});

const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("error msg");
  }, 300);
});
const promise4 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("error error");
  }, 400);
});

const promise = Promise.race([promise1, promise2, promise3, promise4]);
promise
  .then((res) => {
    console.log("res", res);
  })
  .catch((err) => {
    console.log("err", err);
  });

//res 111

Promise类的any方法


const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(111);
  }, 100);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(222);
  }, 200);
});

const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("error msg");
  }, 300);
});
const promise4 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("error error");
  }, 400);
});

const promise = Promise.any([promise1, promise2, promise3, promise4]);
promise
  .then((res) => {
    console.log("res", res);
  })
  .catch((err) => {
    console.log("err", err);
  });

//res 111

const promise11 = Promise.any([promise3, promise4]);
promise11
  .then((res) => {
    console.log("res", res);
  })
  .catch((err) => {
    console.log("err", err);
    console.log('err', err.errors)
  });

  // err [AggregateError: All promises were rejected]
  // err [ 'error msg', 'error error' ]

非常感谢王红元老师的深入JavaScript高级语法让我学习到很多 JavaScript 的知识

上一篇 下一篇

猜你喜欢

热点阅读