回调函数与promise与async/await

仅个人回忆向,初学不是很懂写下来加深印象,也欢迎大佬进行讲解和补充

首先在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

链接:juejin.cn/post/714430...

来源:稀土掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

例如:

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 是一种用于处理异步操作的编程模式,相对于使用回调函数,它具有以下几个区别:

  1. 可链式调用:Promise 提供了 `.then()` 方法,使得可以链式调用多个异步操作。这样可以避免回调地狱(callback hell)的问题,使得代码更加清晰易读。

  2. 错误处理:Promise 提供了 `.catch()` 方法,用于捕获和处理异步操作中的错误。这样可以集中处理错误,而不需要在每个回调函数中进行错误检查和处理。

  3. 更好的可读性:Promise 使用 `.then()` 和 `.catch()` 方法来处理异步操作的结果,使得代码的逻辑更加清晰和易于理解。

  4. 更好的错误追踪:Promise 可以捕获和跟踪异步操作中的错误,并将错误信息传递给 `.catch()` 方法。这样可以更容易地追踪错误的来源和调试代码。

  5. 更好的组合和复用性:Promise 可以通过 `.then()` 方法将多个异步操作链接在一起,形成一个操作序列。这样可以更方便地组合和复用异步操作。

总的来说,Promise 提供了一种更优雅和可读性更高的方式来处理异步操作。它能够减少回调地狱的问题,提供更好的错误处理和追踪机制,并提供更好的组合和复用性。

3.async/await也没比promise好啊,用async还要用trycatch获取错误,感觉比promise更麻烦

使用 async/awaittry-catch 的主要优势在于代码的可读性和可维护性。它们使异步代码看起来更像是同步代码,使得逻辑更加清晰和直观。

使用 async/await 可以避免回调地狱(callback hell)的问题,使异步代码更易于编写和理解。通过在异步操作前使用 await 关键字,代码可以暂停执行,直到异步操作完成并返回结果。这使得异步操作的处理更加直观和线性。

使用 try-catch 可以更容易地捕获和处理异步操作中的错误。在 try 块中执行异步操作,如果操作失败,则会抛出一个错误。然后可以在 catch 块中捕获该错误,并执行相应的错误处理逻辑。

尽管在某些情况下使用 async/awaittry-catch 可能会增加一些额外的代码,但它们提供了更好的代码结构和错误处理机制,使得代码更加健壮和可维护。

当然,选择使用 async/await 还是 Promise 取决于个人偏好和项目需求。有些情况下,使用 Promise 可能更适合简单的异步操作。但对于复杂的异步操作和更清晰的代码结构,async/awaittry-catch 是更好的选择。

4.用async/await时都要用到trycatch吗

在使用 async/await 时,并不是每个异步操作都需要使用 try-catch 块来捕获错误。try-catch 主要用于捕获可能发生的异常并进行错误处理。

在使用 async/await 时,可以根据需要决定是否使用 try-catch 块来捕获错误。以下是一些常见的情况:

  1. 如果您希望在发生错误时执行特定的错误处理逻辑,可以使用 try-catch 块来捕获错误并在 catch 块中处理它们。

    async function main() {

    try {

    const data = await fetchData();

    console.log(data);

    } catch (error) {

    console.log('An error occurred:', error);

    // 执行错误处理逻辑

    } }

  2. 如果您希望让错误向上传递到调用 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 块来捕获错误取决于您的需求和代码结构。在某些情况下,您可能希望在异步操作的特定位置进行错误处理,而在其他情况下,您可能希望将错误向上传递到调用函数的地方进行处理。

结语

暂时先写到这么多,一时接收这么多昏昏沉沉的,大概是理解了,但是用还不好说哈哈.

相关推荐
前端没钱10 分钟前
若依Nodejs后台、实现90%以上接口,附体验地址、源码、拓展特色功能
前端·javascript·vue.js·node.js
爱喝水的小鼠15 分钟前
AJAX(一)HTTP协议(请求响应报文),AJAX发送请求,请求问题处理
前端·http·ajax
叫我:松哥31 分钟前
基于机器学习的癌症数据分析与预测系统实现,有三种算法,bootstrap前端+flask
前端·python·随机森林·机器学习·数据分析·flask·bootstrap
让开,我要吃人了34 分钟前
HarmonyOS鸿蒙开发实战(5.0)网格元素拖动交换案例实践
前端·华为·程序员·移动开发·harmonyos·鸿蒙·鸿蒙开发
谢尔登42 分钟前
Webpack 和 Vite 的区别
前端·webpack·node.js
谢尔登43 分钟前
【Webpack】Tree Shaking
前端·webpack·node.js
过期的H2O21 小时前
【H2O2|全栈】关于CSS(4)CSS基础(四)
前端·css
纳尼亚awsl1 小时前
无限滚动组件封装(vue+vant)
前端·javascript·vue.js
八了个戒1 小时前
【TypeScript入坑】TypeScript 的复杂类型「Interface 接口、class类、Enum枚举、Generics泛型、类型断言」
开发语言·前端·javascript·面试·typescript
西瓜本瓜@1 小时前
React + React Image支持图像的各种转换,如圆形、模糊等效果吗?
前端·react.js·前端框架