ES6中的Promise对象与async和await方法详解
在ES6之前,JavaScript的异步编程需要使用回调函数,这种方式常常导致代码难以阅读和维护。ES6引入Promise对象和async/await方法,使得异步编程更加易于理解和控制。
Promise对象
Promise对象是ES6提供的一种异步编程的解决方案,是一个代表一个异步操作的最终结果的对象。Promise对象有3个状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。
创建Promise对象
通过Promise
构造函数可以创建新的Promise对象,它接受一个函数作为参数,这个函数会立即执行,并接受两个参数resolve
和reject
。
const promise = new Promise(function(resolve, reject) {
// 异步操作
setTimeout(function() {
if (/* 操作成功 */) {
resolve("操作成功");
} else {
reject(new Error("操作失败"));
}
}, 1000);
});
Promise对象的方法
then(onFulfilled, onRejected)
: 当Promise对象的状态变成fulfilled时调用onFulfilled
函数,当状态变成rejected时调用onRejected
函数。这个方法返回一个新的Promise对象。
promise
.then(function(value) {
console.log(value); // "操作成功"
}, function(error) {
console.log(error); // Error: "操作失败"
});
catch(onRejected)
: 相当于then(null, onRejected)
,只捕捉rejected状态的Promise对象。如果Promise对象的状态是fulfilled,则会跳过catch
方法,直接执行后面的then
方法。
promise
.then(function(value) {
console.log(value);
})
.catch(function(error) {
console.log(error); // Error: "操作失败"
});
Promise.all方法
Promise.all
方法可以同时执行多个Promise对象,等待所有Promise对象都显式为fulfilled状态时返回一个新的Promise对象。新的Promise对象的resolved值为一个数组,数组中的元素为每个Promise对象的resolved值,按照传入Promise.all
方法的数组的顺序排列。
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);
Promise.all([promise1, promise2, promise3])
.then(function(values) {
console.log(values); // [1, 2, 3]
});
async/await方法
async
函数是ES7中引入的一种新的异步编程机制,它可以让我们更好的写出异步代码,终止了JavaScript里面多层回调的写法。await
是async
函数的一部分,它可以在线性代码的基础上写出异步的代码,await
后面跟着的是一个返回Promise对象的表达式,await
会暂停async函数的执行,等待Promise对象的resolved值。
async函数
async函数返回一个Promise对象,可以使用Promise的then方法添加回调函数。
async function asyncFunc() {
// 异步操作
return "异步操作完成";
}
asyncFunc().then(function(value) {
console.log(value); // "异步操作完成"
});
await表达式
await表达式会暂停async函数的执行,等待Promise对象的resolved值,并使用其resolved值作为表达式的值。如果Promise对象rejected,则抛出异常。
async function asyncFunc() {
// 异步操作
const resolvedValue = await Promise.resolve("异步操作完成");
console.log(resolvedValue); // "异步操作完成"
}
asyncFunc();
错误处理
在async/await函数内部使用try...catch
语句捕获异步操作中的错误。
async function asyncFunc() {
try {
// 异步操作
const resolvedValue = await Promise.reject(new Error("异步操作失败"));
} catch (error) {
console.log(error); // Error: "异步操作失败"
}
}
asyncFunc();
示例1
下面是一个将使用异步API得到的数组中的所有元素的字符串长度置于数组中并返回的函数。
async function getStringLengthsFromArray() {
try {
const array = await getArrayAsync();
const stringLengths = array.map(function(str) {
return str.length;
});
return stringLengths;
} catch (error) {
console.log(error);
}
}
function getArrayAsync() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(["apple", "banana", "orange"]);
}, 1000);
});
}
getStringLengthsFromArray()
.then(function(stringLengths) {
console.log(stringLengths); // [5, 6, 6]
});
示例2
下面是一个使用async
和await
函数实现的得到用户Github信息的例子:
async function getUserInfo(username) {
try {
const userInfo = await fetch(`https://api.github.com/users/${username}`).then(function(response) {
if (!response.ok) {
throw new Error(response.statusText);
}
return response.json();
});
const repositories = await fetch(userInfo.repos_url).then(function(response) {
if (!response.ok) {
throw new Error(response.statusText);
}
return response.json();
});
userInfo.repositories = repositories;
return userInfo;
} catch (error) {
console.log(error);
}
}
getUserInfo("generalsimus")
.then(function(userInfo) {
console.log(userInfo.repositories); // Array[30]
});
结束语
使用Promise对象和async/await方法可以使得异步编程更加清晰和易于维护。当然,在处理错误的时候也需要注意。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:ES6中的Promise对象与async和await方法详解 - Python技术站