一、Promise简介
Promise是JS中非常重要的概念,它可以用来封装异步操作,让代码更加优雅易读。
Promise是一种设计模式,用于优雅地处理异步操作。它的核心思想是用链式调用的方式,取代了传统的嵌套回调函数。
Promise有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败)。pending状态可以转化为fulfilled或rejected状态。fulfilled和rejected状态一旦发生,都不可以再转化成其他状态。
二、Promise的基本用法
Promise一般包含在一个函数中,函数返回一个Promise对象。当异步操作执行成功时,Promise对象可以resolve,否则可以reject。
下面是一个例子:
function myAsyncFunc() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("我是成功的数据");
}, 1000);
});
}
调用函数myAsyncFunc可以得到返回值为一个Promise对象,可以使用链式调用的方式进行操作,如下:
myAsyncFunc().then(function(data) {
console.log(data);
});
上一步中,使用then方法定义了成功回调函数,这个函数的参数就是resolve传递的值。在链式调用中,可以使用then方法定义一个或多个回调函数,它们会依次执行。
有时候可能会需要在Promise对象上添加一个失败处理函数,可以使用catch方法,如下:
myAsyncFunc().then(function(data) {
console.log(data);
}).catch(function(error) {
console.log(error);
});
如果myAsyncFunc函数reject了,它将会执行catch定义的函数。
三、Promise的进阶用法
1. Promise.all
Promise.all方法接收一个包含Promise对象的数组,当它们全部完成后,Promise.all返回一个新的Promise对象,它的resolve值是一个包含每个Promise对象成功返回值的数组。
如果任何一个Promise对象reject了,这个新的Promise对象就会reject,返回第一个reject的Promise的错误信息。
let promise1 = Promise.resolve('数据1');
let promise2 = Promise.resolve('数据2');
let promiseArr = Promise.all([promise1, promise2]);
promiseArr.then(function(data) {
console.log(data);
});
上述代码会输出数组[‘数据1’, ‘数据2’]。
2. Promise.race
Promise.race方法接受一个包含Promise对象的数组,返回一个新的Promise对象,这个对象将会与第一个完成的Promise对象保持相同状态。
如果第一个Promise对象reject了,这个新的Promise对象就会reject,返回第一个reject的Promise的错误信息。
let promise1 = new Promise(function(resolve, reject){
setTimeout(function() {
resolve("数据1");
}, 1000);
});
let promise2 = new Promise(function(resolve, reject){
setTimeout(function() {
resolve("数据2");
}, 2000);
});
let promiseArr = Promise.race([promise1, promise2]);
promiseArr.then(function(data) {
console.log(data);
});
在上述代码中,第一个Promise对象”数据1″会在1秒后resolve,第二个Promise对象”数据2″会在2秒后resolve,但promiseArr会返回第一个resolve的Promise对象”数据1″。
3. Promise.resolve和Promise.reject
Promise.resolve方法返回一个被解析的Promise对象,这个对象处于fulfilled状态。如果传入的是一个非Promise对象,它将会被转化为一个Promise对象,即resolve(obj)等价于返回 new Promise(resolve => resolve(obj))。
Promise.reject方法返回一个被reject的Promise对象,这个对象处于rejected状态。
let promiseArr = Promise.all([
Promise.resolve('数据1'),
Promise.resolve('数据2'),
Promise.reject('失败的数据')
]);
promiseArr.then(function(data) {
console.log(data);
}).catch(function(error) {
console.log(error);
});
在上述代码中,其中一个Promise对象返回了reject状态,所以将会在catch中输出”失败的数据”。
四、JSPromise示例
下面是一个基于JSPromise实现流程控制的示例,用于说明在实际开发中如何利用Promise对象进行流程控制。
let request = indexedDB.open('testDB', 1);
let promise = JSPromise();
request.onsuccess = function() {
promise.resolve(request.result);
};
request.onerror = function() {
promise.reject(request.error);
};
request.onupgradeneeded = function() {
let db = request.result;
let objectStore = db.createObjectStore('books', {keyPath: 'id'});
objectStore.createIndex('name', 'name', {unique: false});
};
promise.then(function(db) {
let store = db.transaction('books', 'readwrite').objectStore('books');
return JSPromise(function(resolve) {
store.add({id: 1, name: 'JavaScript设计模式', price: 45.00, publisher: '人民邮电出版社'}).onsuccess = function() {
resolve(store);
};
});
}).then(function(store) {
return JSPromise(function(resolve) {
store.add({id: 2, name: 'JavaScript高级程序设计', price: 99.00, publisher: '人民邮电出版社'}).onsuccess = function() {
resolve(store);
};
});
}).then(function(store) {
return JSPromise(function(resolve) {
store.add({id: 3, name: 'JavaScript语言精粹', price: 29.00, publisher: '人民邮电出版社'}).onsuccess = function() {
resolve(store);
};
});
}).then(function(store) {
let index = store.index('name');
return JSPromise(function(resolve) {
index.get('JavaScript高级程序设计').onsuccess = function(event) {
let object = event.target.result;
resolve(object);
};
});
}).then(function(object) {
console.log(object);
}).catch(function(error) {
console.log(error);
});
上述代码中,使用indexedDB来存储一些书籍的数据。在存储数据过程中,使用了多个Promise对象实现流程控制,从indexedDB打开到操作数据的增删改查,最后输出了满足查询条件的某一个书籍的信息。
五、总结
通过本文的阐述,我们了解了Promise的基本用法、进阶用法,以及一个基于JSPromise的流程控制示例。合理的使用Promise可以让代码更加优雅、易读,增加代码的可维护性和健壮性。
原创文章,作者:XWHWH,如若转载,请注明出处:https://www.506064.com/n/370291.html