回调地狱
相信小伙伴们在日常开发中会经常碰到类似开发场景:
setTimeout(function(){ console.log('陕西西安'); setTimeout(function () { console.log('广东深圳'); setTimeout(function () { console.log('浙江杭州'); },1000) },2000) },3000)
上述场景我们称之为回调地狱。
回调地狱:在回调函数中再嵌套回调函数的情况(是实现代码顺序执行的一种操作方式)
(1)代码的可读性差、可维护性差
(2)代码的扩展性差
Promise简介
Promise 是异步编程的一种解决方案:
从语法上讲,promise是一个对象,从它可以获取异步操作的消息;
从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。
promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态);
状态一旦改变,就不会再变。
创造promise实例后,它会立即执行。
Promise用处
promise是用来解决以下问题:1.回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象
2.promise可以支持多个并发的请求,获取并发请求中的数据
Promise API
创建实例
<script> //实例化 Promise 对象 const p = new Promise(function(resolve, reject){ setTimeout(function(){ // let data = '数据库中的用户数据'; // resolve(data); let err = '数据读取失败'; reject(err); }, 1000); }); //调用 promise 对象的 then 方法 p.then(function(value){ console.log(value); }, function(reason){ console.error(reason); }) </script>Promise的构造函数接收一个参数:函数,并且这个函数需要传入两个参数:
resolve :异步操作执行成功后的回调函数
reject:异步操作执行失败后的回调函数
then方法
调用 then 方法,then方法的返回结果是 Promise 对象, 对象状态由回调函数的执行结果决定。 1. 如果回调函数中返回的结果是非promise类型的属性, 状态为成功, 返回值为对象的成功的值。 2.如果回调函数中返回的结果是promise对象, 状态为该promise对象中的状态。 3.如果抛出错误,状态为失败,返回值是对象的失败的值。<script> const p = new Promise((resolve, reject) => { setTimeout(() => { resolve('用户数据'); // reject('出错啦'); }, 1000) }); const result = p.then(value => { console.log(value); //1. 非 promise 类型的属性 // return 'iloveyou'; //2. 是 promise 对象 // return new Promise((resolve, reject) => { // resolve('ok'); // // reject('error'); // }); //3. 抛出错误 // throw new Error('出错啦!'); throw '出错啦!'; }, reason => { console.warn(reason); }).then(value => { console.log(value); }, reason => { console.warn(reason); }); </script>
catch方法
我们知道Promise对象除了then方法,还有一个catch方法,它是做什么用的呢?其实它和then的第二个参数一样,用来指定reject的回调。用法是这样:
<script> const p = new Promise((resolve, reject)=>{ setTimeout(()=>{ //设置 p 对象的状态为失败, 并设置失败的值 reject("出错啦!"); }, 1000) }); // p.then(function(value){}, function(reason){ // console.error(reason); // }); p.catch(function(reason){ console.warn(reason); }); </script>
效果和写在then的第二个参数里面一样。不过它还有另外一个作用:在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中。与try/catch语句有相同的功能。
Promise.all方法
Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。
let Promise1 = new Promise(function(resolve, reject){}) let Promise2 = new Promise(function(resolve, reject){}) let Promise3 = new Promise(function(resolve, reject){}) let p = Promise.all([Promise1, Promise2, Promise3]) p.then(funciton(){ // 三个都成功则成功 }, function(){ // 只要有失败,则失败 })有了all,就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据。
Promise.race方法
//请求某个图片资源 function requestImg(){ var p = new Promise((resolve, reject) => { var img = new Image(); img.onload = function(){ resolve(img); } img.src = '图片的路径'; }); return p; } //延时函数,用于给请求计时 function timeout(){ var p = new Promise((resolve, reject) => { setTimeout(() => { reject('图片请求超时'); }, 5000); }); return p; } Promise.race([requestImg(), timeout()]).then((data) =>{ console.log(data); }).catch((err) => { console.log(err); });requestImg函数会异步请求一张图片,我把地址写为"图片的路径",所以肯定是无法成功请求到的。timeout函数是一个延时5秒的异步操作。我们把这两个返回Promise对象的函数放进race,于是他俩就会赛跑,如果5秒之内图片请求成功了,那么进入then方法,执行正常的流程。如果5秒钟图片还未成功返回,那么timeout就跑赢了,则进入catch,报出“图片请求超时”的信息。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。