salesforce学习笔记(3-1)- JavaScript Promise(LWC)

发布时间 2023-04-07 18:03:23作者: 乔木船长

在JS代码中,Promise到底有什么作用?

首先,我们知道的是,Javascript是单线程的,什么意思呢?就是说JS在同一时间只能做一个操作,代码的执行是一行一行进行的:

 

 

这种执行方式带来的问题就是在我们打开某个画面的时候,画面可能会卡住转圈、加载中状态很久,用户体验感很差。

Promise可用于资源加载或异步操作,于是,用Promise方法便能解决这个问题。

以下,是使用Promise的方法例图:

 

 

 上图对应代码如下:

 1 let shouldBeResolve = true; 
 2 
 3 const promise = new Promise((resolve, reject) => {
 4   setTimeout(() => {
 5       if (shouldBeResolve) {
 6           resolve('success!');
 7       }
 8 
 9       reject('failed!');
10   }, 1000);
11 });
12 
13 // then/catch
14 const thenCatchApproach = () => {
15   promise
16     .then((result) => {
17       console.log(`thenCatchApproach result => ${result}.`);
18     })
19     .catch((error) => {
20       console.log(`thenCatchApproach error => ${error}.`);
21     })
22     .finally(() => {
23       console.log('thenCatchApproach done.');
24     })
25 }
26 
27 // async/await
28 const asyncAwaitApproach = async () => {
29   try {
30     const result = await promise;
31     console.log(`asyncAwaitApproach result => ${result}.`);
32   } catch (error) {
33     console.error(error);
34     console.log(`asyncAwaitApproach error => ${error}.`);
35   } finally {
36     console.log('asyncAwaitApproach done.');
37   }
38 }
39 
40 // success
41 shouldBeResolve = true;
42 
43 thenCatchApproach();
44 asyncAwaitApproach();

Promise主要有以下三种状态:

  • pending: 初始状态
  • fulfilled: 意味着操作执行成功
  • rejected: 意味着操作失败

同时,由上图可看出,then/catchasync/await非常相似,都可以用来解决Promise问题。

那么,两者有什么区别呢?

使用async/await将暂停函数执行,直到Promise有结果(resolve或者reject)。因此,此异步行为表现得有点像同步。

 1 function myPromiseFunction() {
 2     return new Promise((resolve, reject) => {
 3         setTimeout(() => {
 4             resolve('Success');
 5         }, 2000);
 6     });
 7 }
 8 
 9 (async () => {
10     console.log('Start');
11     const result = await myPromiseFunction();
12     console.log(`result - ${result}`);
13     console.log('End');
14 })();

而then/catch则是将继续执行逻辑,直到Promise有结果JS将会执行then()方法回调。

 1 function myPromiseFunction() {
 2     return new Promise((resolve, reject) => {
 3         setTimeout(() => {
 4             resolve('Success');
 5         }, 2000);
 6     });
 7 }
 8 
 9 (() => {
10     console.log('Start');
11     myPromiseFunction()
12         .then(result => {
13             console.log(`result - ${result}`);
14         })
15         .catch(error => {
16             console.error(error);
17         })
18     console.log('End');
19 })();

接下来,就是在LWC中,Promise的使用情况了。

在LWC中,所有的Apex方法都返回一个Promise对象。

 1 import apexMethodName from '@salesforce/apex/Namespace.Classname.apexMethodReference'; 

我们可以通过三种方式使用上述apex方法:

  • @wire
  • Then/Catch
  • Async/Await

Wire

使用场景:

  • 返回的数据结果可以被缓存,@wire的apex方法需要被标记为(Cacheable=true)
  • @wire只可以用来读取数据,不支持DML操作(insert,update,delete)

对于一个属性:

1 import apexMethodName from '@salesforce/apex/Namespace.Classname.apexMethodReference';
2 
3 @wire(apexMethodName, { apexMethodParams })
4 property;

对于一个方法:

 1 import apexMethodName from '@salesforce/apex/Namespace.Classname.apexMethodReference';
 2 
 3 @wire(apexMethodName, { apexMethodParams })
 4 wiredFunction({ error, data }) {
 5     if (data) {
 6         console.log(data);
 7     } else if (error) {
 8         console.error(error);
 9     }
10 }

Then/Catch

使用场景:

  • 需要对数据库进行DML操作(insert,update,delete)
  • 数据不能被缓存
  • 应该用户操作(如onclick事件)后调用该apex方法
 1 mport apexMethodName from '@salesforce/apex/Namespace.Classname.apexMethodReference';
 2 
 3 apexMethodName
 4     .then(result => {
 5         console.log(result);
 6     })
 7     .catch(error => {
 8         console.error(error);
 9     })
10     .finally(() => {
11         console.log('done.'); //good place to hide spinner
12     })

Async/Await

使用场景:

  • 需要对数据库进行DML操作(insert,update,delete)
  • 数据不能被缓存
  • 应该用户操作(如onclick事件)后调用该apex方法
  • 代码应该表现为同步
1 import apexMethodName from '@salesforce/apex/Namespace.Classname.apexMethodReference';
2 
3 try {
4     let result = await apexMethodName;
5 } catch (error) {
6     console.error(error);
7 } finally {
8     console.log('done.'); //good place to hide spinner
9 }

多个await链式执行

 1 import { LightningElement } from 'lwc';
 2 
 3 import apexMethod1 from '@salesforce/apex/ClassName.apexMethod1';
 4 import apexMethod2 from '@salesforce/apex/ClassName.apexMethod2';
 5 import apexMethod3 from '@salesforce/apex/ClassName.apexMethod3';
 6 
 7 export default class LwcPromise extends LightningElement {
 8 
 9     connectedCallback() {
10         this.invokeApexMethods();
11     }
12 
13     async invokeApexMethods() {
14         try {
15             const result1 = await apexMethod1();
16             const result2 = await apexMethod2({ param: result1 });
17             const result3 = await apexMethod3({ param: result2 });
18         } catch(error) {
19             console.error(error);
20         } finally {
21             console.log('Finally Block');
22         }
23     }
24 }

Async/Await总结:

异步方法总会返回一个Promise对象。Await只能被用在被标记为async(异步)的方法里。

 

欢迎评论转发,如文中有问题欢迎指正!

Copyright © 乔木船长

博客主页:https://www.cnblogs.com/captainqiaomu/