仅个人回忆向,初学不是很懂写下来加深印象,也欢迎大佬进行讲解和补充
首先在JavaScript中,有两种常见的方法来实现异步函数:
1.使用回调函数(Callback):这是一种传统的方法,在异步操作完成后,通过调用一个回调函数来处理结果。
(个人理解:回调函数就是执行异步函数的东西,异步执行完了就调用"回调函数"来处理)
例如:
scss
function fetchData(callback) {
setTimeout(function() {
const data = 'Async data';
callback(data);
}, 1000);
}
function handleData(data) {
console.log(data);
}
fetchData(handleData);
在上面的例子中,fetchData
函数模拟了一个异步操作,通过setTimeout
函数模拟1秒后返回数据。handleData
函数作为回调函数传递给fetchData
函数,在异步操作完成后被调用来处理返回的数据。
2.使用Promise对象:Promise是ES6中引入的一种处理异步操作的机制。它可以更方便地处理异步操作的结果,并且可以链式调用多个异步操作。
(个人理解:promise用来解决回调地狱,链式调用(.then)错误处理(.catch)和更好的可读性)
Promise
(承诺),给予调用者一个承诺,过一会返回数据给你,就可以创建一个promise对象- 当我们
new
一个promise
,此时我们需要传递一个回调函数,这个函数为立即执行的,称之为(executor) - 这个回调函数,我们需要传入两个参数回调函数,
reslove
,reject
(函数可以进行传参)-
当执行了
**reslove**
函数,会回调promise对象的.then函数 -
当执行了
**reject**
函数,会回调promise对象的.catche函数
-
作者:一只ice
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
例如:
javascript
function fetchData() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
const data = 'Async data';
resolve(data);
}, 1000);
});
}
fetchData().then(function(data) {
console.log(data);
}).catch(function(error) {
console.log(error);
});
在上面的例子中,fetchData
函数返回一个Promise对象。在异步操作完成后,调用resolve
方法来传递结果。通过调用then
方法来处理成功的情况,调用catch
方法来处理失败的情况。
这两种方法都可以实现异步函数,选择使用哪种方法取决于具体的需求和项目的要求。
3.async和await
使用 async/await
可以将上述代码重写为以下形式:
javascript
function fetchData() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
const data = 'Async data';
resolve(data); }, 1000);
});
}
async function main() {
try {
const data = await fetchData();
console.log(data);
} catch (error) {
console.log(error);
}
}
main();
在上述代码中,fetchData
函数返回一个 Promise 对象,并使用 setTimeout
模拟一个异步操作。在 main
函数中,我们使用 await
关键字来等待 fetchData
函数返回的 Promise 对象。当异步操作完成时,我们可以访问解决值并打印到控制台。如果异步操作失败,我们可以使用 try-catch
块来捕获错误并打印到控制台。
个人提问环节
1.使用await关键字可以使异步操作看起来更像同步操作,但它并不会阻塞整个程序的执行,举个例子.
当使用await关键字等待一个异步操作完成时,JavaScript引擎会继续执行其他可以执行的代码。下面是一个简单的例子来说明这一点:
javascript
async function fetchData() {
console.log("Start fetching data");
// 模拟一个异步操作,例如发送HTTP请求
await new Promise(resolve => setTimeout(resolve, 2000));
console.log("Data fetched");
}
console.log("Before calling fetchData");
fetchData();
console.log("After calling fetchData");
在这个例子中,我们定义了一个名为fetchData的异步函数。在函数内部,我们使用await关键字等待一个模拟的异步操作,即一个2秒钟的延迟。在异步操作完成之前,我们在控制台输出"Start fetching data"。然后,我们在控制台输出"After calling fetchData"。 当我们运行这段代码时,输出将会是:
kotlin
Before calling fetchData
Start fetching data
After calling fetchData
Data fetched
从输出结果可以看出,在调用fetchData函数之后,控制台会立即输出"After calling fetchData",而不会等待异步操作完成。然后,在异步操作完成后,控制台输出"Data fetched"。 这个例子说明了使用await关键字时,虽然函数的执行被暂停等待异步操作完成,但整个程序的执行并没有被阻塞,它可以继续执行其他可以执行的代码。
2.promise相对于用回调函数的区别
Promise 是一种用于处理异步操作的编程模式,相对于使用回调函数,它具有以下几个区别:
-
可链式调用:Promise 提供了 `.then()` 方法,使得可以链式调用多个异步操作。这样可以避免回调地狱(callback hell)的问题,使得代码更加清晰易读。
-
错误处理:Promise 提供了 `.catch()` 方法,用于捕获和处理异步操作中的错误。这样可以集中处理错误,而不需要在每个回调函数中进行错误检查和处理。
-
更好的可读性:Promise 使用 `.then()` 和 `.catch()` 方法来处理异步操作的结果,使得代码的逻辑更加清晰和易于理解。
-
更好的错误追踪:Promise 可以捕获和跟踪异步操作中的错误,并将错误信息传递给 `.catch()` 方法。这样可以更容易地追踪错误的来源和调试代码。
-
更好的组合和复用性:Promise 可以通过 `.then()` 方法将多个异步操作链接在一起,形成一个操作序列。这样可以更方便地组合和复用异步操作。
总的来说,Promise 提供了一种更优雅和可读性更高的方式来处理异步操作。它能够减少回调地狱的问题,提供更好的错误处理和追踪机制,并提供更好的组合和复用性。
3.async/await也没比promise好啊,用async还要用trycatch获取错误,感觉比promise更麻烦
使用 async/await
和 try-catch
的主要优势在于代码的可读性和可维护性。它们使异步代码看起来更像是同步代码,使得逻辑更加清晰和直观。
使用 async/await
可以避免回调地狱(callback hell)的问题,使异步代码更易于编写和理解。通过在异步操作前使用 await
关键字,代码可以暂停执行,直到异步操作完成并返回结果。这使得异步操作的处理更加直观和线性。
使用 try-catch
可以更容易地捕获和处理异步操作中的错误。在 try
块中执行异步操作,如果操作失败,则会抛出一个错误。然后可以在 catch
块中捕获该错误,并执行相应的错误处理逻辑。
尽管在某些情况下使用 async/await
和 try-catch
可能会增加一些额外的代码,但它们提供了更好的代码结构和错误处理机制,使得代码更加健壮和可维护。
当然,选择使用 async/await
还是 Promise
取决于个人偏好和项目需求。有些情况下,使用 Promise
可能更适合简单的异步操作。但对于复杂的异步操作和更清晰的代码结构,async/await
和 try-catch
是更好的选择。
4.用async/await时都要用到trycatch吗
在使用 async/await
时,并不是每个异步操作都需要使用 try-catch
块来捕获错误。try-catch
主要用于捕获可能发生的异常并进行错误处理。
在使用 async/await
时,可以根据需要决定是否使用 try-catch
块来捕获错误。以下是一些常见的情况:
-
如果您希望在发生错误时执行特定的错误处理逻辑,可以使用
try-catch
块来捕获错误并在catch
块中处理它们。async function main() {
try {
const data = await fetchData();
console.log(data);
} catch (error) {
console.log('An error occurred:', error);
// 执行错误处理逻辑
} }
-
如果您希望让错误向上传递到调用
main
函数的地方进行处理,可以在调用main
函数的地方使用try-catch
块来捕获错误。
javascript
async function main() {
const data = await fetchData();
console.log(data);
}
try {
main();
} catch (error) {
console.log('An error occurred:', error);
// 执行错误处理逻辑
}
3.如果您不需要特定的错误处理逻辑,并且希望让错误向上传递到调用 main
函数的地方进行处理,可以省略 try-catch
块。
javascript
async function main() {
const data = await fetchData();
console.log(data);
}
main().catch(error => {
console.log('An error occurred:', error);
// 执行错误处理逻辑
});
总之,使用 try-catch
块来捕获错误取决于您的需求和代码结构。在某些情况下,您可能希望在异步操作的特定位置进行错误处理,而在其他情况下,您可能希望将错误向上传递到调用函数的地方进行处理。
结语
暂时先写到这么多,一时接收这么多昏昏沉沉的,大概是理解了,但是用还不好说哈哈.