123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- //! Promise对象
- // Promise 就是 “承诺” 的意思。代表未来某个时间要发生的事。它的出现是为了更好的处理异步任务。
- //! 1. 同步与异步
- var a = 10;
- console.log(a);
- var b = 20;
- console.log(b);
- //COMMENT 上面代码 都属于 同步代码 即我们所说的同步任务
- //! 同步的特点是,代码 是 自顶向下 一行一行的执行,只有当前行有返回值或者运算完成后,才会执行下一行代码。
- var c = 10;
- console.log(c);
- // 定时器中回调函数 就是 异步代码 即我们所说的异步任务
- setTimeout(() => {
- console.log('timer');
- }, 1000);
- console.log('end');
- // 上面代码 输出的顺序为 : 10,'end', 'timer'
- //! 上面代码 中 包含异步任务,特点是 异步任务不会阻塞同步任务的执行,如果下面还有同步任务,继续执行。也就说 同步任务 此时的执行优先级高于 异步任务。
- //! 小结:在JavaScript中,常见的异步任务:
- /**
- * 1. 事件处理函数
- * 2. 定时器 setTimeout 和 setInterval
- * 3. 网络请求Ajax
- * 4. Promise对象
- * */
- //! 2. 创建Promise对象
- // 语法 const promise = new Promise(executor)
- const promise = new Promise((resolve, reject) => {
- // executor 是同步的回调函数,当new Promise的时候executor会立即执行。
- // 这里就是 要编写的异步任务
- setTimeout(() => {
- // 1.5s后 该异步任务会执行
- // 执行后,要给Promise对象设置状态(成功或者失败),以及异步任务的结果
- // 在 executor中 会接收两个参数 resolve 和 reject
- // resolve(value) 将Promise对象的状态设置为成功的(fulfilled),并将参数value设置为成功的结果值
- // reject(reason) 将Promise对象的状态设置为失败的(rejected),并将参数reason设置为失败的原因
- let n = Math.random(); // 创建一个随件数
- // 如果n大于 0.5 那么成功,结果值 为 n
- if (n > 0.5) {
- resolve(n);
- reject(); // 这里并不会 将promise状态修改为 失败的。由于上面已经调用resolve了 此reject会被忽略
- } else {
- // 否则 失败,失败的原因 为 '你太小了'
- reject('你太小了');
- }
- }, 1500);
- });
- console.log(promise);
- //! 3. 获取Promise对象结果
- // promise.then(
- // (value) => {
- // console.log('你成功了,值为:', value);
- // },
- // (reason) => {
- // console.log('你拜拜了,因为:', reason);
- // }
- // );
- //! promise对象的then方法会返回一个新的Promise对象
- //! 4. Promise对象 还有一个 专门用于处理失败的方法 catch
- promise
- .then((value) => {
- console.log('你成功了,值为:', value);
- })
- .catch((reason) => {
- console.log('你拜拜了,因为:', reason);
- });
- //COMMENT 上面代码 由于then方法没有传入失败的处理函数,因此一旦promise失败了,就会将状态和结果都交给then返回的新Promise对象上,然后就可以通过新Promise对象调用catch方法去处理失败的情况了。
- //! 5 静态方法 就是 构造函数的方法 Promise.resolve(value)
- // 直接返回一个Promise对象,通过状态为 成功的,以及成功的值为value参数。value可以为任何值。
- console.log(Promise.resolve(1));
- //! 6 静态方法 就是 构造函数的方法 Promise.reject(reason)
- // 直接返回一个Promise对象,通过状态为 失败的,以及失败的原因为reason参数。reason可以为任何值。
- console.log(Promise.reject('我就失败了咋地!!!'));
- //! 6 回调地狱
- // 举栗子:
- // 假如 有3个定时器:A - 1s后执行,B - 3s后执行,C - 2s后执行,但是要求 A 执行后 在执行B,B执行后 在执行C。
- setTimeout(() => {
- console.log('任务A完事了');
- // 开启任务B
- setTimeout(() => {
- console.log('任务B完事了');
- setTimeout(() => {
- console.log('任务C完事了');
- }, 2000);
- }, 3000);
- }, 1000);
- //! 在上述代码中的实现 你会发现 setTimeout中的回调函数 一直在嵌套下去,一旦这种异步任务 需要有序的、像同步任务那样一个一个的执行,就会产生一种现象--回调地狱。影响代码的可读性,也就说维护这样的代码会变得困难。
- //! 6.1 使用Promsie对象来解决
- function taskA() {
- return new Promise((resolve) => {
- setTimeout(() => {
- resolve('任务A完事了');
- }, 1000);
- });
- }
- function takB() {
- return new Promise((resolve) => {
- setTimeout(() => {
- resolve('任务B完事了');
- }, 3000);
- });
- }
- function taskC() {
- return new Promise((resolve) => {
- setTimeout(() => {
- resolve('任务C完事了');
- }, 2000);
- });
- }
- taskA()
- .then((v) => {
- console.log(v);
- return taskB();
- })
- .then((v) => {
- console.log(v);
- return taskC();
- })
- .then((v) => {
- console.log(v);
- });
- //! 由于AP.then方法中的回调函数 指定了 返回值 为 一个新的Promise对象BP,因此 AP.then方法它自己返回的Promise对象的状态就和BP关联,同理后面也是一样的道理。
- var p1 = Promise.resolve(1).then((v) => {
- console.log(`output->v`, v);
- });
- console.log(p1); // p1 就是 then方法返回值Promise对象
- var p2 = Promise.reject(1).catch((v) => {
- console.log(`output->v`, v);
- });
- console.log(p2); // p2 就是 catch方法返回值Promise对象
|