Javascript 如何使用finally在promise对象上使用then和catch

Javascript 如何使用finally在promise对象上使用then和catch

Javascript的异步编程使用promise对象,它不会阻塞当前流的执行,但会告诉编译器有一些尚未完成的事情,并在完成时向系统返回一个信号。主要有两种可能性,promise对象要么成功完成,要么通过返回异常而停止。为了处理来自promise对象的异常,我们使用catch()方法。在try-catch方法中,我们也可以使用另一个名为’finally’的代码块。无论之前做了什么,它都会被执行。对于promise对象,我们也可以使用finally()函数来实现相同的效果。因此,在本文中,我们的最终目标是了解如何使用finally在promise对象上使用then()和catch()方法。

基本语法如下所示-

语法

promise
   .then(
      // do something with the result
      result => { ...}
   )
   .catch(
      // handle error
      error => { ... }
   )
   .finally(
      // do something when it has been executed successfully
      // or raised an error.
      // this work can be memory cleaning or similar task
      () => { ... }
   )

无论承诺接受还是拒绝,finally()方法总是会执行。换句话说,当调用finally()过程时,承诺被解决。在ES2018中,finally()函数首次亮相。无论承诺的结果如何,都可以将销毁资源的代码放在finally()方法中。如果不使用finally()方法,我们必须在then()和catch()方法中清除资源。

无finally方法

promise
   .then(
      // do something with the result
      result => { ...}
      // do something to clear resources
   )
   .catch(
      // handle error
      error => { ... }
      // do something to clear resources
   )

then()和catch()代码块包含着重复的代码。通过添加一个finally()代码块,可以轻松避免这种重复。try…catch…finally语句的finally代码块和finally()函数是相关的结构。在同步编程中,使用finally代码块进行资源清理。而在异步程序中,则使用finally()方法。

让我们看一个示例,我们创建一个“Connection”类来创建数据库连接(假设)。有两种不同的方法,run()方法用于执行查询,另一个方法叫做terminate()用于终止连接和清理资源。连接类的定义如下:

连接类

class Connection {
   run( query ) {
      if (query != 'Add' && query != 'Modify' && query != 'Remove') {
         throw new Error( `Invalid query: {query}`);
      }
      console.log(`Running given query:{query}`);
      return this;
   }
   terminate() {
      console.log( 'Terminating already connected connection' )
   }
}

然后我们定义一个connect()方法,它将创建一个连接对象并返回一个promise对象来处理连接。当它完成其操作时,将返回一个新的连接对象,否则将引发错误。让我们看看connect方法的函数定义,以便清楚理解。

连接方法

class Connection {
   run( query ) {
      if (query != 'Add' && query != 'Modify' && query != 'Remove') {
         throw new Error( `Invalid query: {query}`);
      }
      console.log(`Running given query:{query}`);
      return this;
   }
   terminate() {
      console.log( 'Terminating already connected connection' )
   }
}

使用finally()方法来处理最后的情况。在下面的示例中:因为成功标志被设置为true,connect()函数解析为一个新的Connection对象。Insert查询通过第一个then()方法执行,该方法还返回一个Connection对象。连接通过globalConnection保存。Select查询由第二个then()函数运行,该函数还会抛出一个错误。finally()方法结束连接,catch()方法显示错误消息。

使用finally方法

let globalConnection;

connect()
   .then( (connection) => {
      globalConnection = connection;
      return globalConnection.run( 'Add' );
   })
   .then( (connection) => {
      globalConnection = connection;
      return globalConnection.run( 'Remove' );
   })
   .then((connection) => {
      globalConnection = connection;
      return connection.run( 'Union' );
   })
   .catch( console.log )
   .finally( () => {
      if ( globalConnection ) {
         globalConnection.terminate();
      }
   });

完整的代码和相应的输出如下:

源代码

class Connection {
   run( query ) {
      if (query != 'Add' && query != 'Modify' && query != 'Remove') {
         throw new Error( `Invalid query: {query}`);
      }
      console.log(`Running given query:{query}`);
      return this;
   }

   terminate() {
      console.log( 'Terminating already connected connection' )
   }
}

const success = true;
function connect() {
   return new Promise( (resolve, reject) => {
      if ( success )
         resolve( new Connection() );
      else
         reject( 'Connection cannot be created' );
      });
   }
   let globalConnection;
   connect()
   .then( (connection) => {
      globalConnection = connection;
      return globalConnection.run( 'Add' );
   })
   .then( (connection) => {
      globalConnection = connection;
      return globalConnection.run( 'Remove' );
   })
   .then((connection) => {
      globalConnection = connection;
      return connection.run( 'Union' );
   })
   .catch( console.log )
   .finally( () => {
      if ( globalConnection ) {
      globalConnection.terminate();
   }
});

输出

Running given query: Add
Running given query: Remove
Error: Invalid query: Union
    at Connection.run (/home/cg/root/18775/main.js:4:16)
    at /home/cg/root/18775/main.js:36:25
Terminating already connected connection

使用finally()方法来处理承诺,当承诺成功或拒绝时,会执行一个函数。无论承诺最终结果如何,最好将释放资源的代码放在finally()过程中。

结论

在构建和分发到另一个平台或构建可用平台时,异常处理是一项关键任务。异常处理中使用try-catch代码块。catch代码块的目的是使用已建立的逻辑处理异常。我们还使用与它们一起使用的另一个代码块称为”finally”,它无论是否发生异常都会执行。但是,只有同步系统应该使用这种处理方式。在异步编程中,错误可能会因为延迟响应而在之后出现。为了管理异常,我们可以利用then()方法,它类似于try代码块。然而,在这种情况下,我们使用finally()函数来达到与”finally”代码块相同的结果。每当承诺已成功执行或出现错误时,通常会使用此函数来执行清理操作。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程