```clike
```handlebars
```handlebars
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//ES6规定,Promise对象是一个构造函数,用来生成Promise实例
/*
Promise构造函数接受一个函数作为参数,
该函数的两个参数分别是resolve和reject.
它们是两个函数,由JavaScript引擎提供,不用自己部署.
resolve函数的作用是,将Promise对象的状态从 "未完成" 变为 "成功"
(即从pending变为rejected),在异步操作失败时调用,
并将异步操作报出的错误,作为参数传递出去
*/
// const romise = new Promise(function(resolve,reject){
// //...some code
// if ('/* 异步操作成功 */'){
// resolve(value);
// } else{
// reject(error);
// }
// })
/*
Promise实例生成以后,
可以用then方法分别指定resolved状态和rejected状态的回调函数。
then方法可以接受两个回调函数作为参数,
第一个回调函数是Promise对象的状态变为resolve时调用,
第二个回调函数是Promise对象的状态变为rejected时调用。
这两个函数都是可选的,不一定要提供。它们都接受Promise对象传出的值作为参数
*/
// Promise.then(
// function(value){
// //success
// },
// function(error){
// //failuer
// }
// );
//eg:
function timeout(ms) {
return new Promise((resolve,reject) => {
setTimeout(resolve,ms,'done');
});
}
timeout(100).then((value) =>{
console.log(value)
});
/*
上述代码中,timeout方法返回一个Promise实例,
表示一段时间以后才会发生的结果,
过了指定的时间(ms参数)以后,Promise实例的状态变为resolved,
就会触发then方法绑定的回调函数
*/
//Promise新建后就会立即执行
let promise = new Promise(function(resolve,reject){
console.log('Promise');
resolve();
})
promise.then(function(){
console.log('resolved.');
});
console.log('Hi!!!!!');
//Promise
//Hi!!!!
//resolved
/*
上述代码中,Promise新建后立即执行,所以首先输出的时Promise.
然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,
所以resolved最后输出
*/
//eg:异步加载图片
function loadImageAsync(url){
return new Promise(function(resolve,reject) {
const image =new Image();
image.onload = function() {
resolve(image);
};
image.onerror = function() {
reject(new Error('Could not load image at ' +url));
};
image.src = url;
});
}
/*
上述代码中,使用Promise包装了一个图片加载的异步操作,
如果加载成功,就调用resolve方法,否则就调用reject方法
*/
//eg:用Promise对象实现的Ajax操作的例子:
// const getJSON = function(url) {
// const promise = new Promise(function(resolve,reject){
// const handler = function() {
// if (this.readyState !==4) {
// return;
// }
// if (this.status ==200){
// resolve(this.response);
// } else {
// reject(new Error(this.statusText));
// }
// };
// const client = new XMLHttpRequest();
// client.open('GET',url);
// client.onreadystatechange = handler;
// client.responseType = 'json';
// client.setRequestHeader("Accept","application/json");
// client.send();
// });
// return promise;
// };
// getJSON("/posts.json").then(function(json){
// console.log('Contents:'+json);
// },function(error){
// console.error('出错了',error);
// });
/*
上述代码中,getJSON是对XMLHttpRequest对象的封装,
用于发出一个针对JSON数据的http请求,并且返回一个Promise对象。
需要注意的是,在getJSON内部,resolve函数和reject函数调用时,都带有参数。
如果调用resolve函数和reject函数时1带有参数,那么它们的参数会被传递给回调函数。
reject的回调函数通常是error对象的实例,表示抛出的错误,
resolve函数的参数除了正常的值以外,还可能是另一个promise实例,eg:
*/
const p1 = new Promise(function(resolve,reject) {
//....
});
const p2 = new Promise(function (resolve,reject){
//...
resolve(p1);
})
/*
上述代码中,p1和p2都是Promise的实例,
但是p2的resolve方法将p1作为参数,即一个异步操作的结果是返回另一个异步操作。
注意,这时p1的状态就会传递给p2,也就是说p1的状态决定了p2的状态。
如果p1的状态是pending,那么p2的回调函数就会等待p1的状态改变;
如果p1的状态已经是resolved或者是rejected,那么p2的回调函数将会立即执行
*/
// const p1 = new Promise(function(resolve,reject) {
// setTimeout(() => reject(new Error('fail')),3000)
// })
// const p2 = new Promise(function (resolve,reject) {
// setTimeout(() => resolve(p1),1000)
// })
// p2
// .then(result => console.log(result))
// .catch(error => console.log(error))
//输出结果 Error:fail
/*
上述代码中,p1是一个Promise,3秒之后变为rejected。
p2的状态在1秒之后改变,resolve方法返回的是p1。
由于p2返回的是另一个promise,导致p2自己的状态无效了,由p1的额状态决定p2的状态。
所以,后面的then语句都变成针对后者(p1).
又过了2秒,p1变为rejectd,导致触发catch方法指定的回调函数
注意:调用resolve或reject并不会终结Promise的参数函数的执行
*/
new Promise((resolve,reject) => {
resolve(1);
console.log(2);
}).then (r => {
console.log(r);
});
//2
//1
/*
上述代码中,调用resolve(1)以后,后面的console.log(2)还是会执行,并且会首先打印出来。
这是因为立即resolved的Promise是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。
一般来说,调用resolve或reject后,Promise的使命就完成了,后续操作应该放在then方法里面,
而不应该直接写在resolve或者reject的后面。
所以,最好在它们前面加上return语句,这样就不会有意外。
*/
new Promise((resolve, reject) => {
return resolve(1);
// 后面的语句不会执行
console.log(2);
})
</script>
</body>
</html>