这种执行方式带来的问题就是在我们打开某个画面的时候,画面可能会卡住转圈、加载中状态很久,用户体验感很差。
Promise可用于资源加载或异步操作,于是,用Promise方法便能解决这个问题。
以下,是使用Promise的方法例图(图片来自于网络):
上图对应代码如下:
let shouldBeResolve = true;
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldBeResolve) {
resolve('success!');
}
reject('failed!');
}, 1000);
});
// then/catch
const thenCatchApproach = () => {
promise
.then((result) => {
console.log(`thenCatchApproach result => ${result}.`);
})
.catch((error) => {
console.log(`thenCatchApproach error => ${error}.`);
})
.finally(() => {
console.log('thenCatchApproach done.');
})
}
// async/await
const asyncAwaitApproach = async () => {
try {
const result = await promise;
console.log(`asyncAwaitApproach result => ${result}.`);
} catch (error) {
console.error(error);
console.log(`asyncAwaitApproach error => ${error}.`);
} finally {
console.log('asyncAwaitApproach done.');
}
}
// success
shouldBeResolve = true;
thenCatchApproach();
asyncAwaitApproach();
Promise主要有以下三种状态:
- pending: 初始状态
- fulfilled: 意味着操作执行成功
- rejected: 意味着操作失败
同时,由上图可看出,then/catch和async/await非常相似,都可以用来解决Promise问题。
那么,两者有什么区别呢?
使用async/await将暂停函数执行,直到Promise有结果(resolve或者reject)。因此,此异步行为表现得有点像同步。
function myPromiseFunction() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Success');
}, 2000);
});
}
(async () => {
console.log('Start');
const result = await myPromiseFunction();
console.log(`result - ${result}`);
console.log('End');
})();
而then/catch则是将继续执行逻辑,直到Promise有结果JS将会执行then()方法回调。
function myPromiseFunction() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Success');
}, 2000);
});
}
(() => {
console.log('Start');
myPromiseFunction()
.then(result => {
console.log(`result - ${result}`);
})
.catch(error => {
console.error(error);
})
console.log('End');
})();
2、Salesforce LWC中Promise的使用情况
在LWC中,所有的Apex方法都返回一个Promise对象。
import apexMethodName from ‘@salesforce/apex/Namespace.Classname.apexMethodReference’;
我们可以通过三种方式使用上述apex方法:
- @wire
- Then/Catch
- Async/Await
2-1、Wire
使用场景:
- 返回的数据结果可以被缓存,@wire的apex方法需要被标记为(Cacheable=true)
- @wire只可以用来读取数据,不支持DML操作(insert,update,delete)
对于一个属性:
import apexMethodName from '@salesforce/apex/Namespace.Classname.apexMethodReference'; @wire(apexMethodName, { apexMethodParams }) property;
对于一个方法:
import apexMethodName from '@salesforce/apex/Namespace.Classname.apexMethodReference';
@wire(apexMethodName, { apexMethodParams })
wiredFunction({ error, data }) {
if (data) {
console.log(data);
} else if (error) {
console.error(error);
}
}
2-2、Then/Catch
使用场景:
- 需要对数据库进行DML操作(insert,update,delete)
- 数据不能被缓存
- 应该用户操作(如onclick事件)后调用该apex方法
import apexMethodName from '@salesforce/apex/Namespace.Classname.apexMethodReference';
apexMethodName
.then(result => {
console.log(result);
})
.catch(error => {
console.error(error);
})
.finally(() => {
console.log('done.'); //good place to hide spinner
})