一些js的用法 ,持续添加 , 记录一下 GGbond 一年多的成长 , 避免忘记
什么是异步编程?
在JavaScript中,当我们执行一个函数时,它会阻塞线程,直到该函数完成。这意味着,如果我们在执行函数时遇到一个耗时的操作(如读取文件或从网络中获取数据),整个应用程序将被阻塞,直到该操作完成。这就是同步编程。
异步编程的目的是解决这个问题。异步编程允许我们在执行耗时操作时继续执行应用程序的其他部分,而不必等待该操作完成。
Promise的三种状态和状态转换
- Promise有三种状态:pending、fulfilled和rejected。
- 创建Promise对象时,它的初始状态是pending。
- 异步操作成功完成时,Promise对象的状态变为fulfilled。
- 异步操作失败时,Promise对象的状态变为rejected。
要改变Promise的状态,必须调用resolve()或reject()函数。
在使用Promise时,我们只需要简单地创建一个Promise对象,然后使用then()方法来注册成功后的回调函数,或者使用catch()方法来注册失败后的回调函数。当Promise对象的状态发生变化时,相应的回调函数就会被调用。
以下是一个使用Promise的示例,演示了Promise的三种状态和状态转换:
const promise = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
const random = Math.random()
if (random > 0.5) {
resolve('数据已经返回')
} else {
reject('发生了错误')
}
}, 1000)
})
promise.then(result => {
console.log(result) // '数据已经返回'
}).catch(error => {
console.log(error) // '发生了错误'
})
在这个例子中,我们使用Promise对象来模拟一个异步操作。当异步操作完成后,Promise对象的状态将变为fulfilled,并调用then()方法中的回调函数。如果异步操作失败,Promise对象的状态将变为rejected,并调用catch()方法中的回调函数。
Promise常用方法
Promise.prototype.then(): Promise对象从pending到fulfilled状态时的回调函数。可以使用多个then()方法注册多个回调函数,按照它们注册的顺序依次执行。如果Promise对象已经fulfilled,相应的回调函数将立即执行。如果Promise对象是pending,相应的回调函数将在Promise对象变为fulfilled时执行。Promise.prototype.catch(): Promise对象从pending到rejected状态时的回调函数的回调函数,。可以注册多个回调函数,按照它们被注册的顺序依次调用。如果Promise对象的状态已经是rejected,相应的回调函数会立即被调用。如果Promise对象的状态是pending,相应的回调函数将在Promise对象的状态变为rejected时被调用。。Promise.resolve(): 创建一个已经fulfilled状态的Promise对象。我们可以使用Promise.resolve()方法来返回一个已经完成的Promise对象,并使用then()方法来注册成功后的回调函数。如果我们需要在Promise对象执行完成后立即返回结果,我们可以使用Promise.resolve()方法。Promise.reject(): 创建一个已经rejected状态的Promise对象。我们可以使用Promise.reject()方法来返回一个已经失败的Promise对象,并使用catch()方法来注册失败后的回调函数。如果我们需要在Promise对象执行完成后立即返回错误信息,我们可以使用Promise.reject()方法。Promise.all(): 将多个Promise对象组合为一个Promise对象,并返回所有Promise对象的结果数组(元素一一对应)。当所有Promise对象都成功完成时,Promise.all()将返回一个已完成的Promise对象,并传递异步操作的结果数组。如果Promise对象数组中的任何一个对象被拒绝,Promise.all()方法就会返回一个已拒绝的Promise对象,并传递相应的错误信息。
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('数据1已经返回')
}, 1000)
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('数据2已经返回')
}, 2000)
})
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('发生了错误')
}, 3000)
})
Promise.all([promise1, promise2, promise3])
.then(results => {
console.log(results) // ['数据1已经返回', '数据2已经返回']
})
.catch(error => {
console.log(error) // '发生了错误'
})
当所有Promise对象都成功完成时,Promise.all()将返回一个已完成的Promise对象,并传递异步操作的结果数组。如果Promise对象数组中的任何一个对象被拒绝,Promise.all()方法就会返回一个已拒绝的Promise对象,并传递相应的错误信息。在这个例子中,由于第三个Promise对象被拒绝,catch()方法被调用,并传递相应的错误信息。
Promise.race(): 将多个Promise对象组合为一个Promise对象,并返回最先完成的Promise对象的结果。当任何一个Promise对象变为fulfilled或rejected状态时,Promise.race()方法就将返回一个已经完成或失败的Promise对象,并传递相应的结果或错误信息。
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('数据1已经返回')
}, 1000)
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('数据2已经返回')
}, 2000)
})
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('发生了错误')
}, 3000)
})
Promise.race([promise1, promise2, promise3])
.then(result => {
console.log(result)
})
.catch(error => {
console.error(error)
})
在这个例子中,我们使用Promise.race()方法来等待多个异步操作中的最快一个完成。如果第一个Promise对象完成,我们将得到它的结果。
Promise.race()和Promise.all()的区别
因此,Promise.race()和Promise.all()的主要区别在于它们返回的Promise对象的结果不同。Promise.race()返回最先完成的Promise对象的结果,而Promise.all()返回所有Promise对象的结果数组。so :
Promise.race()方法通常用于设置超时,而Promise.all()方法通常用于并行处理多个异步操作。
async/Await
async/await是基于Promise的,它使用async和await关键字来定义异步函数。
使用async/await也很简单。我们可以定义一个异步函数,使用await关键字来等待异步操作完成,并返回异步操作的结果。
例如,以下是一个使用async/await的示例:
async function fetchData() {
// 异步操作
const result = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve('数据已经返回')
}, 1000)
})
console.log(result) // '数据已经返回'
}
fetchData()
比较Promise和async/await
我们已经介绍了Promise和async/await两种异步编程技术。那么,它们之间有什么区别呢?
Promise是基于回调的,它使用then()和catch()方法来处理异步操作。async/await是基于Promise的,它使用async和await关键字来定义异步函数。
Promise和async/await都有优缺点。Promise容易理解和处理错误,但它容易陷入回调地狱。async/await使代码更易读,但它可能会使错误处理变得更加困难。
Promise陷入回调地狱的原因在于,当我们需要执行多个异步操作时,我们需要嵌套多个then()方法调用,这使得代码难以阅读和维护。例如,以下是一个使用Promise的回调地狱示例:
fetch(url1)
.then(response1 => {
// 第一个异步操作完成后执行第二个异步操作
fetch(url2)
.then(response2 => {
// 第二个异步操作完成后执行第三个异步操作
fetch(url3)
.then(response3 => {
// ...
})
})
})
async/await可能会使处理错误变得更加困难,因为我们需要使用try/catch语句来处理异步函数中的错误,如果我们在异步操作中使用多个await关键字,我们需要为每个await语句编写try/catch语句。例如 :
async function fetchData() {
try {
// 异步操作
const response = await fetch(url)
const data = await response.json()
console.log(data)
} catch (error) {
console.error(error)
}
}
总结
- Promise的三种状态和状态转换,以及使用then()和catch()方法来处理异步操作。
- async/await使用async和await关键字来定义异步函数,使得异步编程变得更加简单和易读。
- Promise和async/await都有优缺点,Promise容易理解和处理错误,但容易陷入回调地狱;async/await使代码更易读,但可能会使错误处理变得更加困难。