Salesforce Javascript(一) Promise 浅谈
本篇参看:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Using_promises

我们在做lwc开发的时候,必须要查看lwc的开发文档。上图我们可以经常用到,lwc的wire adapter提供的创建记录的方法,我们可以看到return的内容是一个Promise对象,而且文档中涉及到异步创建或者加载文档等方法通常说都返回一个Promise对象,对于前端不好的小伙伴可能想的是, Promise是啥怎么用呢?
一. Promise是什么
说起Promise定义和应用以前,我们先从他的汉语以及日常业务场景进行简单的解释。
Promise 的中文可以解释为承诺,做一个简单的业务场景分析。
年会了,老板喝酒的时候和你碰了个杯,小张啊,今年表现不错,10天以后就是绩效评定,今年必须给你升职加薪。
对于此时的你来说,两种想法。
A. 老板这么器重我啊,马上就要升职加薪、迎娶白富美、走上人生巅峰,想想还有点小激动。我要更加努力奋斗balabala。
B. 可能老板喝多了,算了,我还是安安静静的搬好我的砖吧。
所以说承诺可能具有以下的情况。
1. 承诺将给你一个保证,这个保证自己做别人做怎么实行,不清楚也不重要,重要的是他给了你承诺,你可以在这个承诺的基础上做你计划的事情。上面的例子中,老板给了你承诺,不管是HR联系你还是老板找你谈,不重要,重要的是老板给你了一个约定,给你升职加薪。
2. 既然是一个承诺,他就会有两种情况,要么遵守,要么违约。
3. 虽然我们不知道这个承诺当时的状态,但是我们可以计划一下我们期望从这个承诺达到什么东西,也需要去计划一下如果违背了承诺我们怎么处理。比如涨薪以后买个手机或者出去旅游等等,如果不涨薪就安心搬砖或者跳槽等等。
4. 承诺应该具有时效性。老板10天以内没有联系你,半年以后老板想起来了,哎呀,我之前忘了,今年一定要给你升职加薪。这对于你来说已经不重要了,因为已经过了时效,默认就应该认为是违约了。
5. 承诺通常都不是当时就一下子做的,通常都应该有一定时间进行异步操作。
所以我们通过中文的了解的现实承诺的场景,去了解一下 js中的Promise的概念。
先看一下MDN上面对于Promise的解释:Promise 对象用于表示一个异步操作的最终完成 (或失败), 及其结果值.也就是说 Promise通常用于异步操作或者加载资源或者IO等等非同步有阻塞的操作。我们对 Promise有了一个大概的使用场景的了解,那么 Promise如何声明如何使用呢,接下来慢慢展开。先看一下 Promise的声明
new Promise( function(resolve, reject) {...} /* executor */ );
参数是一个叫做 executor的函数,包括了两个参数, resolve 以及reject,当然这两个参数也都是函数。当 Promise创建以后,会立即执行 executor函数,此时的状态为pending,executor通常操作异步函数,当异步的结果回来有两种可能,成功或者失败。成功的情况下会回调 resolve并且将promise的状态更改为fulfilled,失败的情况下会将Promise的状态更改为rejected并且调用 reject函数,如果异步抛出了异常,则Promise的状态变成 rejected,executor的返回值将被忽略。
这样描述乱乱的,将这个分拆一些细节点。
1. Promise只拥有三种状态: pending (初始状态)、 fulfilled(操作成功)、rejected(操作失败)。其中fulfilled & rejected也可以概括成settled(已定型)。
2. Promise 对象是一个代理对象(代理一个值),被代理的值在Promise对象创建时可能是未知的。它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers)。 这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise对象。
Promise最终只允许两个结果: pending -> fulfilled 或者是 pending -> rejected。Promise方法封装了一个 then方法,包括两个参数, onfulfilled以及onRejected,这两个参数都是函数类型,当 pending -> fulfilled ,会调用 onfulfilled函数,当pending -> rejected,则会调用 onRejected函数。
通过这张图可以看出来, Promise不管是执行了 onFulfillment还是 onRejection,返回的类型仍然是 Promise,这就意味着,可以进行多个 Promise的套用。我们在lwc中通常也会遇见多个调用的方式,比如 通过 getRecord获取 account 以后,理论上返回一个 Promise,我们在 then操作时,可以继续请求后台,去获取 关联的Opportunity等等,Promise可以实现俄罗斯套娃方式的调用。

解释的很难以理解,来个例子简单了解一下。方法中我们声明了一个Promise,在函数中,调用了 resolve,为了模拟异步操作,使用定时器模拟一下,然后调用 then函数去打印输出。
let promise = new Promise(function(resolve,reject) {
setTimeout(() => resolve(2),1000);
});
promise.then((res) => console.log(res));
结果如下:初始化的时候, Promise是 Pending状态,当1秒以后,调用了 resolve方法,所以输出了2, 此时 promise的状态应该是 fulfilled。

再来看一下reject的效果
let promise = new Promise(function(resolve,reject) {
setTimeout(() => reject(2),1000);
});
promise.then((res) => console.log(res));
结果如下:

上图中我们还截图了Promise的方法,Promise原型的方法返回的仍然是 Promise,有三个方法可供选择:then/ catch/ finally。举个例子更好的了解。我们针对 Promise也通常这么书写。
let bossPromise = new Promise(function(resolve, reject) {
resolve({
title: "TL",
increase: "1000"
});
});
bossPromise.then(function(result) {
console.log("哇,我涨薪了,好开心啊 ,老板说我涨了" + JSON.stringify(result));
});
bossPromise.catch(function(reason) {
console.log("没有涨薪,因为老板说我:" + reason);
});
bossPromise.finally(function() {
console.log("涨与不涨都能接受,我都爱公司和这份工作");
});
结果展示:通过截图可以看到,Promise调用了 resolve,状态变成了fulfilled,调用了 then函数,需要注意的是,不管调用了 then还是catch,都需要调用 finally函数。

reject相关的操作:
let bossPromise = new Promise(function(resolve, reject) {
reject({
reason : '能力还得慢慢提高'
});
});
bossPromise.then(function(result) {
console.log("哇,我涨薪了,好开心啊 ,老板说我涨了" + JSON.stringify(result));
});
bossPromise.catch(function(reason) {
console.log("没有涨薪,因为老板说我:" + JSON.stringify(reason));
});
bossPromise.finally(function() {
console.log("涨与不涨都能接受,我都爱公司和这份工作");
});
结果展示:

看到了 then catch操作是不是想象到了 当我们调用后台方法的语法,会有 then 和catch,想的没错,这个操作也是基于 Promise实现。
二. Promise在lwc中的使用
前面说过,Promise主要用于异步或者加载资源,因为异步lwc已经封装好了,所以说我们在lwc中使用 Promise大部分是加载资源用。比如我们需要使用外部的css / javascript。上传到 static resource以后,如何引入使之在lwc中有效呢?下面的步骤展示如何加载css或者js资源的步骤。
1. 引入 loadScript或者loadStyle用于javascript / css资源;
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
2.从static resource引入相关的资源
import xxx from '@salesforce/resourceUrl/xxx';
3. 使用 Promise.all用来执行一组 Promise, loadScript / loadStyle是lwc封装好的方法,用来执行 Promise并且返回类型也是 Promise。 Promise.all方法详情可以查看上面的连接。我们只需要 renderedCallback调用 Promise.all即可。详情参看:https://developer.salesforce.com/docs/component-library/documentation/en/lwc/js_third_party_library总方法如下:
// libsD3.js
/* global d3 */
import { LightningElement } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
import D3 from '@salesforce/resourceUrl/d3';
import DATA from './data'; export default class LibsD3 extends LightningElement {
svgWidth = 400;
svgHeight = 400; d3Initialized = false; renderedCallback() {
if (this.d3Initialized) {
return;
}
this.d3Initialized = true; Promise.all([
loadScript(this, D3 + '/d3.v5.min.js'),
loadStyle(this, D3 + '/style.css')
])
.then(() => {
this.initializeD3();
})
.catch(error => {
this.dispatchEvent(
new ShowToastEvent({
title: 'Error loading D3',
message: error.message,
variant: 'error'
})
);
});
} initializeD3() {
console.log('test');
}
}
总结:篇中只是简单描述Promise的介绍以及使用,有错误地方欢迎指出,有不懂欢迎留言。
Salesforce Javascript(一) Promise 浅谈的更多相关文章
- 私人定制javascript事件处理机制(浅谈)
看到园子里关于事件监听发表的文章,我都有点不好意思写了.不过想想我的题目以私人定制作开头也就妥妥地写吧. 事件相关概念 1.事件类型 发生事件的字符串 有传统事件类型 比如表单.window事件等 D ...
- JavaScript DOM操作浅谈
1.理解DOM: DOM(Document Object Model ,文档对象模型)一种独立于语言,用于操作xml,html文档的应用编程接口. 怎么说,我从两个角度理解: 对于JavaScript ...
- Salesforce Consumer Goods Cloud 浅谈篇一之基础介绍
本篇参考: https://baike.baidu.com/item/%E6%B6%88%E8%B4%B9%E5%93%81/425802?fr=aladdin https://help.salesf ...
- Salesforce Consumer Goods Cloud 浅谈篇二之门店产品促销的配置
本篇参考:https://documentation.b2c.commercecloud.salesforce.com/DOC1/index.jsp?topic=%2Fcom.demandware.d ...
- Salesforce Consumer Goods Cloud 浅谈篇三之 行动计划(Action Plan)相关配置
本篇参考: https://v.qq.com/x/page/f0772toebhd.html https://v.qq.com/x/page/e0772tsmtek.html https://v.qq ...
- Salesforce Consumer Goods Cloud 浅谈篇四之店内拜访的创建和执行
本篇参考: https://v.qq.com/x/page/f0772toebhd.html https://v.qq.com/x/page/e0772tsmtek.html https://v.qq ...
- 浅谈ES6原生Promise
浅谈ES6原生Promise 转载 作者:samchowgo 链接:https://segmentfault.com/a/1190000006708151 ES6标准出炉之前,一个幽灵,回调的幽灵,游 ...
- 浅谈Angular的 $q, defer, promise
浅谈Angular的 $q, defer, promise 时间 2016-01-13 00:28:00 博客园-原创精华区 原文 http://www.cnblogs.com/big-snow/ ...
- 浅谈javascript函数节流
浅谈javascript函数节流 什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等 ...
随机推荐
- Spring Boot系列(三):Spring Boot整合Mybatis源码解析
一.Mybatis回顾 1.MyBatis介绍 Mybatis是一个半ORM框架,它使用简单的 XML 或注解用于配置和原始映射,将接口和Java的POJOs(普通的Java 对象)映射成数据库中的记 ...
- Nordic52840SDK学习之定时器
Nordic 52840 SDK学习之定时器 今天开始学习52840SDK,特在此处记录学习内容,防止以后忘记,或许可以给以后的初学者提供一些帮助.如有错误,请发邮件至843036544@qq.com ...
- Charles 断点修改Response
前言: 我们可以通过map功能进行重定向,但如果同一个域名进行的是不同请求与返回.此时map在这里就不适用了. 我们可以通关对某一请求进行断点,在进行修改请求或者返回.这样就可以满足我们的需求了. 一 ...
- 测试必须学spring RESTful Service(上)
文末我会说说为什么测试必须学spring. REST REST,是指REpresentational State Transfer,有个精辟的解释什么是RESTful, 看url就知道要什么 看met ...
- Kafka入门(3):Sarama生产者是如何工作的
摘要 在这一篇的文章中,我将从Sarama的同步生产者和异步生产者怎么创建开始讲起,然后我将向你介绍生产者中的各个参数是什么,怎么使用. 然后我将从创建生产者的代码开始,按照代码的调用流程慢慢深入,直 ...
- 软件人如何快速晋升CTO(一)
1.场景描述 软件人如何快速晋升CTO? 实战操作,介绍下如何0成本拥有自己的软件公司,出任CTO/CEO. 2020年 8月16日,软件老王拿到公司的营业执照和公章了,税务登记也一起办理好了 ...
- 2. Bean Validation声明式校验方法的参数、返回值
你必须非常努力,才能干起来毫不费力.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习.关注公众 ...
- Android开发之开源框架OKHTTP的Get请求代码,得到json字符串方法
<span style="white-space:pre"> </span><pre name="code" class=&q ...
- 攻防世界——Misc新手练习区解题总结<1>(1-4题)
第一题this_if_flag: 第一题就不多说了,题目上就给出了flag复制粘贴就可以了 第二题pdf: 下载附件后,得到如下界面 Ctrl+a全选文字,复制出来看看是什么,粘贴后恰好得到flag ...
- MockMvc编写单测
目录 MockMvc 注意点 code 待测试的controller 测试类 github MockMvc 注意点 1.通过spring上下文获取mockmvc对象 @BeforeEach publi ...