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

结语

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

相关推荐
夜斗(dou)几秒前
谷歌开发者工具 - 网络篇
前端·网络·chrome devtools
常常不爱学习7 分钟前
CSS盒子模型(溢出隐藏,块级元素和行级元素的居中对齐,元素样式重置)
前端·css
风抽过的烟头7 分钟前
Python提取字符串中的json,时间,特定字符
前端·python·json
SomeB1oody24 分钟前
【Rust自学】6.3. 控制流运算符-match
开发语言·前端·rust
m0_748256781 小时前
【Django自学】Django入门:如何使用django开发一个web项目(非常详细)
前端·django·sqlite
林小白的日常1 小时前
uniapp中wx.getFuzzyLocation报错如何解决
前端·javascript·uni-app
傻小胖1 小时前
React 脚手架配置代理完整指南
前端·react.js·前端框架
EterNity_TiMe_2 小时前
【论文复现】农作物病害分类(Web端实现)
前端·人工智能·python·机器学习·分类·数据挖掘
余生H2 小时前
深入理解HTML页面加载解析和渲染过程(一)
前端·html·渲染
吴敬悦2 小时前
领导:按规范提交代码conventionalcommit
前端·程序员·前端工程化