ES6 - Promise

1.Promise是什么

  1. 认识Promise
    Promise是异步操作的一种方式
    回调函数
  		document.addEventListener('click', () => {
            console.log('这是异步请求!');
        }, false);
        console.log('这是同步请求!');
  1. 什么时候使用Promise
    Promise一般用来解决层层嵌套的回调函数(回调地域 callback hell)的问题
     * {
            padding: 0;
            margin: 0;
        }
        
        #box {
            width: 180px;
            height: 180px;
            background-color: aquamarine;
            transition: all .5s;
        }
  <div id="box"></div>
 const move = (el, {
            x = 0,
            y = 0
        } = {}, end = () => {}) => {
            el.style.transform = `translate3d(${x}px, ${y}px, 0)`;
            el.addEventListener(
                'transitionend',
                () => {
                    end();
                }, false
            );
        };
        const boxEl = document.getElementById('box');
        const movePromise = (el, point) => {
            return new Promise(resolve => {
                move(el, point, () => {
                    resolve();
                });
            });
        }
        document.addEventListener('click', () => {
            movePromise(boxEl, {
                x: 150
            }).then(() => {
                return movePromise(boxEl, {
                    x: 150,
                    y: 150
                })
            }).then(() => {
                return movePromise(boxEl, {
                    y: 150
                })
            }).then(() => {
                return movePromise(boxEl, {
                    x: 0,
                    y: 0
                })
            })

        });

//promise

 const boxEl = document.getElementById('box');
        document.addEventListener('click', () => {
            move(boxEl, {
                x: 150
            }, () => {
                move(boxEl, {
                    x: 150,
                    y: 150
                }, () => {
                    move(boxEl, {
                        y: 150
                    }, () => {
                        move(boxEl, {
                            x: 0,
                            y: 0
                        });
                    })
                })
            })
        })

2.Promise的使用

  1. 实例化构造函数生成实例对象
    Promise解决的不是回调函数,而是回调地狱
console.log(Promise); //ƒ Promise() { [native code] }
const p = new Promise(() => {});
  1. Promise的状态
    Promise有3种状态, 一开始是pending( 未完成), 执行( reject), 变成fulfilled( resolved), 已成功
    Promise的状态一旦改变,就不会再改变了
        const p = new Promise((resolve, reject) => {
        resolve(); //then -- success
       // 执行resolve,变成rejected,已失败
        pending - > fulfilled

        reject(); //then -- error
        pending - > reject
        });
        console.log(p); 
        //Promise {<pending>} 等待状态  
        //Promise {<fulfilled>: undefined} 成功   
        //Uncaught (in promise) undefined失败
  1. then方法
 		p.then(() => {
            console.log('success');
        }, () => {
            console.log('error');
        })
  1. resolve和reject函数的参数
 const p = new Promise((resolve, reject) => {
            // resolve({
            //     username: 'zhangsan'
            // });
            reject(new Error('err!'));
});
p.then((data) => {
 console.log('success', data); //success {username: "zhangsan"}
}, (data) => {
 console.log('error', data); //error Error: err! 
})

3.then()

  1. 什么时候执行
    pending->fulfilled时,执行then的第一个回调函数
    pending->rejected时,执行then的第二个回调函数
  2. 执行后的返回值
 const p = new Promise((resolve, reject) => {
            resolve();
            // reject();
        });
 const p2 = p.then( () => {}, () => {} ).then.then;
 console.log(p, p2, p === p2); 
 //Promise {<fulfilled>: undefined} undefined false
  1. then方法返回的Promise对象的状态改变
 const p = new Promise((resolve, reject) => {
            // resolve();
            reject();
        });
        p.then(
            () => {
                console.log('success');
            }, () => {
                console.log('err!');
       //在then的回调函数中,return后面的东西,会用Promise包装一下
                return 123
                    // 等价于
                    // return new Promise(resolve => {
                    //     resolve(123);
                    // })
                    //默认返回的永远是成功状态的Promise对象
                    // return new Promise((resolve, reject) => {
                    //     reject('reason');//222err! reason    
                    // })
            }
        ).then(
            (data) => {
                console.log('success222', data);
                return new Promise((resolve, reject) => {
                    resolve('then - 123');
                })
            }, (err) => {
                console.log('222err!', err);
            }
        ).then(
            (data) => {
                console.log('success333', data);
            }, (err) => {
                console.log('333err!', err);
            }
        );

4.catch()

  1. 有什么用
 then(
            data => {},
            err => {}
        );
        then(data => {});
	catch专门用来处理reject状态
    catch本质上是then的特例
then(null, err => {});
  1. 基本用法
new Promise((resolve, reject) => {
                // resolve(123);
                reject('error!');
            }).then(data => {
                console.log(data); //123
            })
            // .then(null, err => {
            //     console.log(err); //error!
            // })
            .catch(err => {
                console.log(err); //error!
                throw new Error('error!');
            }).then(data => {
                console.log(data); //undefined
            }).catch(err => {
                console.log(err); //Error: error!  at 62-catch().html:37
            })

catch() 可以捕获它前面的错误
一般总是建议, Promise对象后面跟catch方法, 这样可以处理Promise内部发生的错误

5.finally()

  1. 什么时候执行
    当Promise状态发生改变时,不论如何变化都会执行,不变化不执行
 		new Promise((resolve, reject) => {
            // resolve(123);
            reject('123');
        }).finally(data => {
            console.log(data);
        }).catch(data => {
            console.log(data);
        })
  1. 本质
    finally()本质上是then()的特例
 new Promise((resolve, reject) => {
                // resolve(123);
                reject('err');
            }).finally(data => {
                console.log(data);
            }).catch(err => {})
            
            //等同于

 new Promise((resolve, reject) => {
            // resolve();
            reject('err!');
        }).then(result => {
            return result;
        }, err => {
            return new Promise((resolve, reject) => {
                reject(err);
            });
        }).then(data => {
            console.log(data);
        }).catch(err => {
            console.log(err);
        });

6.Promise.resolve和Promise.reject

  1. Promise.resolve();
    是成功状态Promise的一种简写
    new Promise(resolve => resolve('success'));
    //简写
    Promise.resolve('foo');

参数
一般参数

  Promise.resolve('foo').then(data => {
            console.log(data); //foo
  })

Promise
当Promise.resolve()接收的是Promise对象时,直接返回这个Promise对象,什么都不做

 const p1 = new Promise(resolve => {
            setTimeout(resolve, 1000, '执行了!');
            // setTimeout(() => {
            //     resolve('执行了!');
            // }, 1000)
        });
        Promise.resolve(p1).then(data => {
            console.log(data); //执行了!
        });
        等价于
        p1.then(data => {
            console.log(data); //执行了!
        })
        console.log(Promise.resolve(p1) === p1); //true

当resolve函数接收的是Promise对象时,后面then会根据传递的Promise对象的状态变化决定执行哪一个回调

        new Promise(resolve => resolve(p1)).then(data => {
            console.log(data); //执行了!
        })

具有than方法的对象

       const thenable = {
            then(resolve, reject) {
                // console.log('then');//then
                resolve('data');
                // reject('data');
            }
        };
        Promise.resolve().then(
            data => console.log(data), //undefined
            err => console.log(err),
        );
        console.log(Promise.resolve(thenable)); 
        //Promise {<pending>};
  1. Promise.reject()
    失败状态Promise的一种简写形式
     new Promise((resolve, reject) => {
            reject('error!');
        }).catch(err => console.log(err));
        等价于
        Promise.reject('error!');

参数
不管什么参数,都会原地不动的向后传递,作为后续方法的参数

 const p1 = new Promise(resolve => {
         setTimeout(resolve, 1000, '执行了!');
});
Promise.reject(p1).catch(err => console.log(err));
 //Promise {<pending>}
 new Promise((resolve, reject) => {
                resolve(123);
            }).then(data => {
                // return data;
                return Promise.reject('error!!');
            }).then(data => console.log(data)) //123
            .catch(err => console.log(err)); //error!

7.Promise.all()

  1. 有什么用
    Promise.all() 关注多个Promise对象的状态变化
    传入多个Promise实例,包装成一个新的Promise实例返回
  2. 基本用法
const delay = ms => {
            return new Promise(resolve => {
                setTimeout(resolve, ms);
            })
        }
        const p1 = delay(1000).then(() => {
            console.log('p1 完成了!');
            return 'p111';
        })
        const p2 = delay(2000).then(() => {
            console.log('p2 完成了!');
            // return 'p222';
            return Promise.reject('error!!');
        })

Promise.all()的状态变化与所有传入的Promise实例对象有关
所有状态都变成resolved,最终状态才会变成resolved
只要有一个变成rejected, 最终的状态就变成rejected

const p = Promise.all([p1, p2]);
        p.then(data => {
            console.log(data);
        }, err => {
            console.log(err);
        });

8.Promise.race()和Promise.allSettled()

 const delay = ms => {
            return new Promise(resolve => {
                setTimeout(resolve, ms);
            })
        }
        const p1 = delay(1000).then(() => {
            console.log('p1 完成了!');
            return 'p111';
        })
        const p2 = delay(2000).then(() => {
            console.log('p2 完成了!');
            // return 'p222';
            return Promise.reject('error!!');
        });
  1. Promise.race()
    Promise.race()的状态取决于第一个完成的Promise实例对象,
    如果第一个失败的成功了,那最终的就成功;
    如果第一个完成的失败了,那最终的就失败
 const racePromise = Promise.race([p1, p2]);
        racePromise.then(data => {
            console.log(data);
        }, err => {
            console.log(err);
        });
  1. Promise.allSettled()
    Promise.allSettled()的状态与传入的Promise状态无关
    永远都是成功的
    它会忠实的记录下各个Promise的表现
 const allSettledPromise = Promise.allSettled([p1, p2]);
        allSettledPromise.then(data => {
            console.log('success', data);
        });

9.Promise()注意事项

  1. resolve或reject函数执行后的代码
    推荐调用resolve或reject函数的时候加上return,不再执行它们后面的代码
 new Promise((resolve, reject) => {
            return resolve(123);
            // return reject('error!');
            console.log('hi');
        });
  1. Promise.all/race/allSettled的参数问题
    参数如果不是Promise数组,会将不是Promise的数组元素转变成Promise对象
Promise.all([1, 2, 3]).then(datas => {
            console.log(datas);
        });
// 等价于
Promise.all([Promise.resolve(1), 
			 Promise.resolve(2), 
    	   	 Promise.resolve(3)]).then(datas => {
           			 console.log(datas);
     })

不只是数组,任何可遍历的都可以作为参数
数组,字符串,Set,Map、Nodelist、arguments

  Promise.all(new Set([1, 2, 3])).then(datas => {
            console.log(datas);
        })
  1. Promise.all/race/allSetted的错误处理
        const delay = ms => {
            return new Promise(resolve => {
                setTimeout(resolve, ms);
            })
        }
        const p1 = delay(1000).then(() => {
            console.log('p1 完成了!');
            // return 'p111';
            return Promise.reject('111error!!');
        });
        // 单独处理
        // .catch(err => {
        //     console.log(err);
        // });
        const p2 = delay(2000).then(() => {
            console.log('p2 完成了!');
            // return 'p222';
            // return Promise.reject('222error!!');
        });

        const allPromise = Promise.all([p1, p2]).then(datas => {
            console.log(datas);
        }).catch(err => {
            console.log(err); //统一处理
        })

错误既可以被单独处理。也可以统一处理
一旦被处理,就不会在其他地方再处理一遍。

10.Promise()的应用

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Promise()的应用</title>
</head>

<body>
    <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201410%2F20%2F20141020162058_UrMNe.jpeg&refer=http%3A%2F%2Fcdn.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1620724097&t=e48d8f05d643c62ec5042ce874da5aa4"
        alt="樱桃小丸子" srcset="" id="img">
    <script>
        // 异步加载图片
        const loadImgAsync = url => {
            return new Promise((resolve, reject) => {
                const img = new Image();
                img.onload = () => {
                    resolve(img);
                };
                img.onerror = () => {
                    reject(`Coult not load images at ${url}`);
                };
                img.src = url;
            });
        }
        const imgDOM = document.getElementById('img');
        loadImgAsync('https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201408%2F19%2F20140819011654_ThLAM.thumb.700_0.png&refer=http%3A%2F%2Fcdn.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1620725034&t=29106a44810fa83ad0fdfaa9c8dfc0b5').then(
            img => {
                console.log(img.src);
                setTimeout(() => {
                    imgDOM.src = img.src;
                }, 2000)
            }
        ).catch(err => {
            console.log(err);
        });
    </script>
</body>

</html>

11.小结

  1. Promise 是什么
    Promise 是异步操作的一种解决方案
    Promise 一般用来解决层层嵌套的回调函数的问题
    Promise 解决的不是回调函数,而是回调地狱
  2. Promise 的状态
    Promise 有 3 种状态
    pending(未完成)
    resolved/fulfilled(已成功)
    rejected(已失败)
    状态一旦变化,就不会再改变了
  3. Promise 的基本用法
    在这里插入图片描述
    推荐在调用 resolve 或 reject 函数的时候加上 return
  4. then()
    pending->resolved 时,执行 then 的第一个回调函数
    pending->rejected 时,执行 then 的第二个回调函数
    状态不改变,then() 的回调函数都不会被执行
    then() 执行后返回一个新的 Promise 对象
    可以通过 return 语句改变返回的 Promise对象的状态
    then() 可以向后传值
    在这里插入图片描述
  5. catch()
    catch 专门用来处理 rejected 状态
    catch 本质上是 then 的特例
    建议 Promise 对象后面要跟 catch 方法,这样可以处理 Promise
    内部发生的错误
  6. finally()
    当 Promise 状态发生变化时,不论如何变化都会执行
    finally() 本质上是 then() 的特例
  7. Promise.resolve() 的本质
    成功状态 Promise 的一种简写形式
    在这里插入图片描述
  8. Promise.resolve() 的参数
    参数是 Promise 实例对象时,直接返回这个 Promise 对象
    参数是具有 then 方法的对象时,会立即执行它的 then 方法
    在这里插入图片描述
  9. Promise.resolve() 的参数
    参数是其他值时,相当于通过 resolve 函数传参
  10. Promise.reject()
    失败状态 Promise 的一种简写形式
    在这里插入图片描述
    不管什么参数,都会原封不动地向后传递,作为后续方法的参数
  11. Promise.all/race/allSettled()
    只要是可遍历的,都可作为参数
    参数的“集合”中若有成员不是 Promise 对象,内部会将其转变成 Promise 对象
    返回一个新的 Promise 实例对象
    错误既可以单独处理,也可以统一处理
  12. Promise.all()
    所有状态都变成 resolved,最终的状态才会变成 resolved
    只要有一个变成 rejected,最终的状态就变成 rejected
  13. Promise.race()
    最终的状态取决于第一个完成的 Promise 实例对象
    如果第一个完成的成功了,那最终的就成功
    如果第一个完成的失败了,那最终的就失败
  14. Promise.allSettled()
    最终的状态永远都是成功的,与传入的 Promise 对象状态无关
    会记录下各个 Promise 的表现
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值