六。实例的finally方法:

promise状态发生变化指的是由初始态变成成功或者失败态

处理错误指的是没有调用catch(失败态实例调用可以执行其回调的then)

finally里面的回调函数只要promise状态发生变化就会执行,但是接收不到参数

这里没有调用then方法,也会报错吗?什么时候报错?

应用场景:处理最终状态,比如js操作数据库,涉及异步操作,可以用promise,最终需要关闭数据库不论成功或者失败

finally的本质:

        new Promise(function (resolve, reject) {
// resolve(1);
reject('reason');
}).finally(function () {
console.log(1);
});
// 相当于下面
new Promise(function (resolve, reject) {
// resolve(1);
reject('reason');
})
.then(
result => {
console.log(1); return result;
},
err => {
console.log(1); return new Promise(function (resolve, reject) {
reject(err);
});
}
);

finally源码

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

七。构造函数Promise的方法

1.Promise.resolve()和Promise.reject()

注意,也不一定Promise.resolve()返回的就是成功状态p,看下面传有then方法的一般对象;

所以data接收的参数是p1实例里resolve的参数,也就是由p1接手了;

疑问:(前面已经解答)

解释为什么有这两个函数

同步异步定时器问题,去掉return问题前面的,为什么有的等1秒,有的不等

注意,挂起的then里面的回调会等当前的正在主车道执行的代码执行完再执行;

源码

    <script>
// 1.Promise.resolve()
// 是成功状态 Promise 的一种简写形式
// new Promise(resolve => resolve('foo'));
// // 简写
// Promise.resolve('foo'); // 参数
// 一般参数
// Promise.resolve('foo').then(data => {
// console.log(data);
// }); // 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); // 当 resolve 函数接收的是 Promise 对象时,后面的 then 会根据传递的 Promise 对象的状态变化决定执行哪一个回调
// new Promise(resolve => resolve(p1)).then(data => {
// console.log(data);
// }); // 具有 then 方法的对象
// function func(obj) {
// obj.then(1, 2);
// }
// func({
// then(resolve, reject) {
// console.log(a, b);
// }
// }); // const thenable = {
// then(resolve, reject) {
// console.log('then');
// resolve('data');
// // reject('reason');
// }
// };
// Promise.resolve(thenable).then(
// data => console.log(data),
// err => console.log(err)
// );
// console.log(Promise.resolve(thenable)); // 2.Promise.reject()
// 失败状态 Promise 的一种简写形式
// new Promise((resolve, reject) => {
// reject('reason');
// });
// 等价于
// Promise.reject('reason'); // 参数
// 不管什么参数,都会原封不动地向后传递,作为后续方法的参数
// const p1 = new Promise(resolve => {
// setTimeout(resolve, 1000, '我执行了');
// });
// Promise.reject(p1).catch(err => console.log(err)); new Promise((resolve, rejcet) => {
resolve(123);
})
.then(data => {
// return data;
// return Promise.resolve(data); return Promise.reject('reason');
})
.then(data => {
console.log(data);
})
.catch(err => console.log(err));
</script>

2.Promise.all()方法

注意,参数里面有rejected实例的情况,只要根据代码执行顺序识别到有一个rejected实例,那么下图的p就变成失败态且接收识别到的失败态reject里面的参数a

等价于const p = Promise.reject(a),p和识别的那个rejected实例不是一个实例,只是参数和状态一样;

还有p由p1p2决定,p1p2赋值还未完成,所以p的赋值也未完成,同步执行时,定时器还没执行,delay函数return出去的也是暂时的,所以pp1p2也是暂时的pending状态,异步执行完毕,return后面的值刷新,delay(1000)delay(2000)的返回值也刷新,pp1p2的赋值也刷新;

如果all里面参数若为空数组的话,默认返回实例状态为成功

  <script>
// 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 'p1';
return Promise.reject('reason');
});
const p2 = delay(2000).then(() => {
console.log('p2 完成了'); return 'p2';
// return Promise.reject('reason');
}); // Promise.all() 的状态变化与所有传入的 Promise 实例对象状态有关
// 所有状态都变成 resolved,最终的状态才会变成 resolved
// 只要有一个变成 rejected,最终的状态就变成 rejected const p = Promise.all([p1, p2]);
p.then(
data => {
console.log(data);
},
err => {
console.log(err);
}
);
</script>
3.Promise.race() 和 Promise.allSettled()
取决于第一个,并不是全等第一个只是状态和参数一样;
关于异步程序执行顺序还有很多不懂(异步没写完)
    <script>
const delay = ms => {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
};
const p1 = delay(1000).then(() => {
console.log('p1 完成了'); return 'p1';
// return Promise.reject('reason');
});
const p2 = delay(2000).then(() => {
console.log('p2 完成了'); // return 'p2';
return Promise.reject('reason');
}); // 1.Promise.race()
// Promise.race() 的状态取决于第一个完成的 Promise 实例对象,如果第一个完成的成功了,那最终的就成功;如果第一个完成的失败了,那最终的就失败
// const racePromise = Promise.race([p1, p2]);
// racePromise.then(
// data => {
// console.log(data);
// },
// err => {
// console.log(err);
// }
// ); // 2.Promise.allSettled()
// Promise.allSettled() 的状态与传入的Promise 状态无关
// 永远都是成功的
// 它只会忠实的记录下各个 Promise 的表现
const allSettledPromise = Promise.allSettled([p1, p2]);
allSettledPromise.then(data => {
console.log('succ', data);
});
</script>
 
4.Promise.any()
 
八。Promise注意事项
    <script>
// 1.resolve 或 reject 函数执行后的代码
// 推荐在调用 resolve 或 reject 函数的时候加上 return,不再执行它们后面的代码
// new Promise((resolve, reject) => {
// // return resolve(123);
// return reject('reason'); // console.log('hi');
// }); // 2.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);
// }); // 3.Promise.all/race/allSettled 的错误处理
const delay = ms => {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}; const p1 = delay(1000).then(() => {
console.log('p1 完成了'); // return 'p1';
return Promise.reject('reason');
});
// .catch(err => {
// console.log('p1', err);
// });
const p2 = delay(2000).then(() => {
console.log('p2 完成了'); return 'p2';
// return Promise.reject('reason');
});
// // .catch(err => {
// // console.log('p2', err);
// }); const allPromise = Promise.all([p1, p2]);
allPromise
.then(datas => {
console.log(datas);
})
.catch(err => console.log(err)); // 错误既可以单独处理,也可以统一处理
// 一旦被处理,就不会在其他地方再处理一遍
</script>

九。promise应用

异步加载图片,停留在当前图片时,趁这个时间浏览器从服务器端加载其他资源,图片,然后点击切换按钮想要切换图片时,就可以显示到页面(通过dom),并不是点击切换才去服务器端加载这个图片

promise里的回调一般不写逻辑,一般写的是什么时候调用resolve或者reject;

如果不用promise的话,就会加两个形参接收回调函数,一个负责图片加载成功该怎么办,一个负责图片加载失败

注意img这里是个对象,是Image构造出来的实例,和dom对象没关系

注意这里的SRC属性是实例img的属性和html dom元素的SRC属性不一样

const img = new Image()只是实例化创建了一个img标签,也可以通过appendchild加入到html结构里

注意img.src=url,src属性值变化就能触发onload和onerror事件,img.src=url这个代码的作用就是一个工具,作用是像服务端发请求拿资源,这就是异步加载图片;

如果传进来的url并没有请求到图片,就会触发error事件

实际开发过程中,可能是点击按钮才切换图片;

如果图片加载失败(url错误)会有这个提示:

    <style>
#img {
width: 80%;
padding: 10%;
}
</style>
</head>
<body>
<img
src="https://img.mukewang.com/5e6af63d00011da318720764.jpg"
alt=""
id="img"
/> <script>
// 异步加载图片
const loadImgAsync = url => {
return new Promise((resolve, reject) => {
const img = new Image(); img.onload = () => {
resolve(img);
}; img.onerror = () => {
reject(new Error(`Could not load image at ${url}`));
}; img.src = url;
});
}; const imgDOM = document.getElementById('img');
loadImgAsync('https://2img.mukewang.com/5f057a6a0001f4f918720764.jpg')
.then(img => {
console.log(img.src);
setTimeout(() => {
imgDOM.src = img.src;
}, 1000);
})
.catch(err => {
console.log(err);
});
</script>

①代码执行loadImgAsync('https://2img.mukewang.com/5f057a6a0001f4f918720764.jpg')时,就会创建img对象,并给img对象赋予具体的src地址:

②此时就会开启网络请求,去网络中某一个具体的位置请求图片,即异步加载图片。图片加载完,就会继续执行如下:

由于图片所在的服务器响应特别快,并且我们的网络特别给力、电脑性能也特别好,因此加载图片这个异步过程会迅速完成,看上去和使用本地图片一样快。但是假设图片所在的服务器响应很慢,那么图片就会很慢的请求回来,举个常见的现象:某些网站,打开后,图片迟迟不展示,此时速度上,就有差异了。

十。如何统一处理错误?Promise参与过程中什么时候会报错?Promise.all等方法返回值是新的promise实例,和传进来的无关;

1.如何统一处理错误:

------------------------------------------------------------------------------------------------------------------------------------------------------

十一。async和await  (使得异步操作变得更加方便。)

async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。

调用async函数时,会立即返回一个Promise对象。

注意await后面放的是一个可以求值的东西(函数调用等)

等待Promise返回结果:  ,如果跟的是promise实例这种情况,会等Promise实例过程中的所有代码全部执行完毕(不论同步异步)如果最终状态为成功态,执行该函数体后面的代码(打印end)

如果最终是失败态实例,该函数体后面的代码(打印end)不会执行且会报错;如果最终是pending状态,该函数体后面的代码(打印end)也不会执行

最新文章

  1. bzoj4443[SCOI2015]小凸玩矩阵
  2. UP board 漫谈(1)——从Atom到UP Board
  3. AutoMapper搬运工之自定义类型转换
  4. Activity类生命周期
  5. elasticsearch单机多实例环境部署
  6. Entity Framework 自动生成CodeFirst代码
  7. Quartz将Job保存在数据库中所需表的说明
  8. pouchdb Conflicts
  9. sdfsdf
  10. hdu_5904_LCIS(DP)
  11. 用JavaScript实现图片剪切效果
  12. SK-Learn 全家福
  13. 创建一个servlet
  14. Fiddler使用简单介绍
  15. Webpack vs Browersify vs SystemJs for SPAs
  16. Ribbon
  17. 6. go数组与冒泡排序
  18. 使整个页面变灰的css代码
  19. 解决Struts2 json-plugin Date或Timestamp等日期格式带T的问题
  20. [JSOI2018]潜入行动

热门文章

  1. 学习Vue过程中遇到的问题---code: &#39;MODULE_NOT_FOUND&#39;
  2. CF1418D Trash Problem
  3. 我做的FFmpeg开源C#封装库Sdcb.FFmpeg
  4. 06#Web 实战:可滑动的标签页
  5. Sequelize.js + Express.js 开发 API
  6. Canvas:绘制矩形
  7. Lambda表达式和Collection集合
  8. MicroPython 之 PYBoard
  9. [NPUCTF2020]EzRSA
  10. Chisel项目中,添加了一个文件,新增了一个模块,但是却编译不出来相应的.v文件,什么原因?