一、Promise对象
1.Promise含义
Promise是JavaScript中的一种对象,用于处理异步操作。它表示一种尚未完成的操作,并且在操作完成后可能会返回一个值。Promise对象有三种状态:pending(进行中)、fulfilled(成功)和rejected(失败)。
当Promise对象处于pending状态时,表示操作尚未完成。当操作完成之后,该Promise对象就会变为fulfilled状态或rejected状态,分别表示操作成功或失败。
通过使用Promise对象,可以更方便地处理异步操作。相比于传统的回调函数方式,Promise对象可以更清晰地表达异步操作的流程和结果。
Promise.prototype.then()和Promise.prototype.catch()方法会返回一个全新的Promise对象,因此它们之间可以进行链式调用。
可以通过new
关键字调用构造函数Promise()
去实例化一个Promise异步对象。
const promise = new Promise((resolve, reject) => {
// ... ...
});
2.Promise示例代码
一个简单易于理解的使用Promise的示例如下:
function asyncFunction() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("你好,异步操作!");
}, 5000);
});
}
asyncFunction()
.then(function(value) {
console.info(value); // 打印"你好,异步操作!"
})
.catch(function(error) {
console.error(error); // 打印错误信息
});
下面的代码通过Promise的异步处理方式来获取XMLHttpRequest的数据:
function getURL(URL) {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open('GET', URL, true);
xhr.onload = function() {
if (xhr.status === 200) {
resolve(xhr.responseText);
} else {
reject(new Error(xhr.statusText));
}
};
xhr.onerror = function() {
reject(new Error(xhr.statusText));
};
xhr.send();
});
}
const URL = "http://www.sina.cn/demo";
getURL(URL)
.then(function onFulfilled(value) {
console.info(value);
})
.catch(function onRejected(error) {
console.error(error);
});
3.Promise构造函数上的原型
1.Promise.prototype.constructor
表示Promise构造函数的原型,以便于在原型上放置then()、catch()、finally()方法。
let promise = new Promise((resolve, reject) => {
// resolve('') or reject('')
});
2.Promise.prototype.then(onFulfilled, onRejected)
then()方法返回一个Promise,两个参数分别是Promise成功或者失败状态的回调函数。如果忽略某个状态的回调函数参数,或者提供非函数参数,then()方法将会丢失该状态的回调信息,但是并不会产生错误。如果调用then()的Promise的状态发生改变,但是then()中并没有对应状态的回调函数,则then()最终将创建一个未经回调函数处理的全新Promise对象,并使用最初的Promise状态来作为这个全新Promise的状态。
let promise = new Promise((resolve, reject) => {
resolve("传递给then内的value值。");
});
promise.then(
value => {
console.info(value); // 打印“传递给then内的value值。”
},
error => {
console.error(error);
}
);
3.Promise.prototype.catch(onRejected)
catch()只处理rejected的情况,该方法返回一个Promise,实质Promise.prototype.then(undefined, onRejected)的语法糖。
let promise = new Promise((resolve, reject) => {
resolve("传递给then内的value值。");
});
promise
.then(
value => {
console.info(value); // 打印“传递给then内的value值。”
},
error => {
console.error(error);
}
);
4.Promise.prototype.finally(onFinally)
finally()方法返回一个Promise,在then()和catch()执行完成之后,都会调用finally指定的回调函数,这样可以避免一些重复的语句同时出现在then()和catch()当中。
let promise = new Promise((resolve, reject) => {
resolve("传递给then内的value值。");
reject("传递给catch内error的值。"); // 此处reject并未被执行,因为Promise状态已经在上面一条语句resolve。
});
promise
.then(value => {
console.info(value);
})
.catch(error => {
console.error(error);
})
.finally(() => {
console.log("执行到finally方法。");
})
/* 打印结果 */
// 传递给then内的value值。
// 执行到finally方法。
包括Eage在内的IE系列浏览器目前都不支持finally()
方法。
4.Promise对象实例方法
1.Promise.resolve(value)
该方法会根据参数的不同,返回不同的Promise对象。当接收Promise对象作为参数的时候,返回的还是接收到的Promise对象;
let jqueryPromise = $.ajax("http://gc.ditu.aliyun.com/geocoding?a=成都市"); // jquery返回的promise对象
let nativePromise = Promise.resolve(jqueryPromise);
nativePromise.then(value => {
console.info(value); // API接口的返回值
});
当接收到thenable类型对象(由ES6 Promise提出的Thenable是指具有.then()方法的对象)的时候,返回一个具有该then方法的全新Promise对象;
let thenablePromise = Promise.resolve(
// thenable类型对象
{
then: (onFulfill, onReject) => {
onFulfill('fulfilled!');
}
}
);
console.log(thenablePromise instanceof Promise) // 打印true
thenablePromise.then(value => {
console.info(value);
}, function(error) {
console.error(error);
});
// true
// fulfilled!
当接收其它数据类型参数的时候(字符串或null
)将会返回一个将该参数作为值的全新Promise对象。
let promise = Promise.resolve([1, 2, 3]);
promise.then(values => {
console.info(values[0]); // 1
});
2.Promise.reject(reason)
返回一个被reason拒绝的Promise,但是与resolve()不同之处在于,即使reject()接收的参数是一个Promise对象,该函数依然会返回一个全新的Promise。
let rejectedPromise = Promise.reject(new Error("this is a error!"));
console.info(
rejectedPromise === Promise.reject(rejectedPromise) // 打印false
);
3.Promise.all(iterable)
当iterable参数中所有Promise都被resolve, 或者参数并不包含Promise时, all()方法返一个回resolve的全新Promise对象。当iterable中一个Promise返回拒绝reject时, all()方法会立即终止并返回一个reject的全新Promise对象。
let promise1 = Promise.resolve(1),
promise2 = Promise.resolve(2),
promise3 = Promise.resolve(3);
Promise.all([promise1, promise2, promise3]).then(results => {
console.info(results); // 打印[1, 2, 3]
});
4.Promise.race(iterable)
当iterable参数数组中的任意一个Promise对象变为resolve或者reject状态,该函数就会立刻返回一个全新的Promise对象,并使用该Promise对象进行resolve或者reject。
let promise1 = Promise.resolve(1),
promise2 = Promise.resolve(2),
promise3 = Promise.resolve(3);
Promise.race([promise1, promise2, promise3]).then(results => {
console.info(results); // 打印 1
});