From bd5be6306ee179be12f4a2b221118091098a6d10 Mon Sep 17 00:00:00 2001 From: David Chesnut Date: Mon, 28 Dec 2020 13:38:19 -0800 Subject: [PATCH] New web worker sample (#96) * initial draft from Shaofeng * add copyright headers * rewrites to readme with images * renaming job variables for clarity * added UI animation for reference * small code and comment cleanups * added correct button icons * added correct button icons * update image * Fixes and cleanup work to readme * update manifests * created cleaner localhost references (#97) Co-authored-by: David Chesnut Co-authored-by: Maarten van Stam --- .../web-worker/functions-worker.js | 93 +++++++ .../web-worker/functions.js | 103 ++++++++ .../web-worker/functions.json | 44 ++++ Excel-custom-functions/web-worker/home.html | 106 ++++++++ .../web-worker/images/button16x16.png | Bin 0 -> 269 bytes .../web-worker/images/button32x32.png | Bin 0 -> 484 bytes .../web-worker/images/button80x80.png | Bin 0 -> 1018 bytes .../web-worker/images/icon-16.png | Bin 0 -> 1596 bytes .../web-worker/images/icon-32.png | Bin 0 -> 2386 bytes .../web-worker/images/icon-80.png | Bin 0 -> 4836 bytes .../images/office-add-ins-my-account.png | Bin 0 -> 87439 bytes .../web-worker/images/upload-add-in.png | Bin 0 -> 7245 bytes .../web-worker/manifest-localhost.xml | 162 ++++++++++++ .../web-worker/manifest.xml | 162 ++++++++++++ .../web-worker/package-lock.json | 161 ++++++++++++ Excel-custom-functions/web-worker/readme.md | 234 ++++++++++++++++++ 16 files changed, 1065 insertions(+) create mode 100644 Excel-custom-functions/web-worker/functions-worker.js create mode 100644 Excel-custom-functions/web-worker/functions.js create mode 100644 Excel-custom-functions/web-worker/functions.json create mode 100644 Excel-custom-functions/web-worker/home.html create mode 100644 Excel-custom-functions/web-worker/images/button16x16.png create mode 100644 Excel-custom-functions/web-worker/images/button32x32.png create mode 100644 Excel-custom-functions/web-worker/images/button80x80.png create mode 100644 Excel-custom-functions/web-worker/images/icon-16.png create mode 100644 Excel-custom-functions/web-worker/images/icon-32.png create mode 100644 Excel-custom-functions/web-worker/images/icon-80.png create mode 100644 Excel-custom-functions/web-worker/images/office-add-ins-my-account.png create mode 100644 Excel-custom-functions/web-worker/images/upload-add-in.png create mode 100644 Excel-custom-functions/web-worker/manifest-localhost.xml create mode 100644 Excel-custom-functions/web-worker/manifest.xml create mode 100644 Excel-custom-functions/web-worker/package-lock.json create mode 100644 Excel-custom-functions/web-worker/readme.md diff --git a/Excel-custom-functions/web-worker/functions-worker.js b/Excel-custom-functions/web-worker/functions-worker.js new file mode 100644 index 000000000..c4e4633a0 --- /dev/null +++ b/Excel-custom-functions/web-worker/functions-worker.js @@ -0,0 +1,93 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +self.addEventListener('message', + function(event) { + var job = event.data; + if (typeof(job) == "string") { + job = JSON.parse(job); + } + + var jobId = job.jobId; + try { + var result = invokeFunction(job.name, job.parameters); + // check whether the result is a promise. + if (typeof(result) == "function" || typeof(result) == "object" && typeof(result.then) == "function") { + result.then(function(realResult) { + postMessage( + { + jobId: jobId, + result: realResult + } + ); + }) + .catch(function(ex) { + postMessage( + { + jobId: jobId, + error: true + } + ) + }); + } + else { + postMessage({ + jobId: jobId, + result: result + }); + } + } + catch(ex) { + postMessage({ + jobId: jobId, + error: true + }); + } + } +); + +function invokeFunction(name, parameters) { + if (name == "TEST") { + return test.apply(null, parameters); + } + else if (name == "TEST_PROMISE") { + return test_promise.apply(null, parameters); + } + else if (name == "TEST_ERROR") { + return test_error.apply(null, parameters); + } + else if (name == "TEST_ERROR_PROMISE") { + return test_error_promise.apply(null, parameters); + } + else { + throw new Error("not supported"); + } +} + +function test(n) { + var ret = 0; + for (var i = 0; i < n; i++) { + ret += Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(50)))))))))); + for (var l = 0; l < n; l++) { + ret -= Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(50)))))))))); + } + } + return ret; +} + + +function test_promise(n) { + return new Promise(function(resolve, reject) { + setTimeout(function() { + resolve(test(n)); + }, 1000); + }); +} + +function test_error(n) { + throw new Error(); +} + +function test_error_promise(n) { + return Promise.reject(new Error()); +} \ No newline at end of file diff --git a/Excel-custom-functions/web-worker/functions.js b/Excel-custom-functions/web-worker/functions.js new file mode 100644 index 000000000..14ba39786 --- /dev/null +++ b/Excel-custom-functions/web-worker/functions.js @@ -0,0 +1,103 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +var SampleNamespace = {}; + +(function(SampleNamespace) { + // The max number of web workers to be created + var g_maxWebWorkers = 4; + + // The array of web workers + var g_webworkers = []; + + // Next job id + var g_nextJobId = 0; + + // The promise info for the job. It stores the {resolve: resolve, reject: reject} information for the job. + var g_jobIdToPromiseInfoMap = {}; + + function getOrCreateWebWorker(jobId) { + var index = jobId % g_maxWebWorkers; + if (g_webworkers[index]) { + return g_webworkers[index]; + } + + // create a new web worker + var webWorker = new Worker("functions-worker.js"); + webWorker.addEventListener('message', function(event) { + var jobResult = event.data; + if (typeof(jobResult) == "string") { + jobResult = JSON.parse(jobResult); + } + + if (typeof(jobResult.jobId) == "number") { + var jobId = jobResult.jobId; + // get the promise info associated with the job id + var promiseInfo = g_jobIdToPromiseInfoMap[jobId]; + if (promiseInfo) { + if (jobResult.error) { + // The web worker returned an error + promiseInfo.reject(new Error()); + } + else { + // The web worker returned a result + promiseInfo.resolve(jobResult.result); + } + delete g_jobIdToPromiseInfoMap[jobId]; + } + } + }); + + g_webworkers[index] = webWorker; + return webWorker; + } + + // Post a job to the web worker to do the calculation + function dispatchCalculationJob(functionName, parameters) { + var jobId = g_nextJobId++; + return new Promise(function(resolve, reject) { + // store the promise information. + g_jobIdToPromiseInfoMap[jobId] = {resolve: resolve, reject: reject}; + var worker = getOrCreateWebWorker(jobId); + worker.postMessage({ + jobId: jobId, + name: functionName, + parameters: parameters + }); + }); + } + + SampleNamespace.dispatchCalculationJob = dispatchCalculationJob; +})(SampleNamespace); + + +CustomFunctions.associate("TEST", function(n) { + return SampleNamespace.dispatchCalculationJob("TEST", [n]); +}); + +CustomFunctions.associate("TEST_PROMISE", function(n) { + return SampleNamespace.dispatchCalculationJob("TEST_PROMISE", [n]); +}); + +CustomFunctions.associate("TEST_ERROR", function(n) { + return SampleNamespace.dispatchCalculationJob("TEST_ERROR", [n]); +}); + +CustomFunctions.associate("TEST_ERROR_PROMISE", function(n) { + return SampleNamespace.dispatchCalculationJob("TEST_ERROR_PROMISE", [n]); +}); + + +// This function will show what happens when calculations are run on the main UI thread. +// The task pane will be blocked until this method completes. +CustomFunctions.associate("TEST_UI_THREAD", function(n) { + var ret = 0; + for (var i = 0; i < n; i++) { + ret += Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(50)))))))))); + for (var l = 0; l < n; l++) { + ret -= Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(50)))))))))); + } + } + return ret; +}); + diff --git a/Excel-custom-functions/web-worker/functions.json b/Excel-custom-functions/web-worker/functions.json new file mode 100644 index 000000000..165721e23 --- /dev/null +++ b/Excel-custom-functions/web-worker/functions.json @@ -0,0 +1,44 @@ +{ + "functions": [ + { + "id": "TEST_UI_THREAD", + "parameters": [ + { + "name": "n" + } + ] + }, + { + "id": "TEST", + "parameters": [ + { + "name": "n" + } + ] + }, + { + "id": "TEST_PROMISE", + "parameters": [ + { + "name": "n" + } + ] + }, + { + "id": "TEST_ERROR", + "parameters": [ + { + "name": "n" + } + ] + }, + { + "id": "TEST_ERROR_PROMISE", + "parameters": [ + { + "name": "n" + } + ] + } + ] +} diff --git a/Excel-custom-functions/web-worker/home.html b/Excel-custom-functions/web-worker/home.html new file mode 100644 index 000000000..9a7094972 --- /dev/null +++ b/Excel-custom-functions/web-worker/home.html @@ -0,0 +1,106 @@ + + + + + Custom functions using WebWorker + + + + + + + + diff --git a/Excel-custom-functions/web-worker/images/button16x16.png b/Excel-custom-functions/web-worker/images/button16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..dd7f2a55fbdbaa799d2e5bc4e294c942d9fc7468 GIT binary patch literal 269 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!9|`fjv*HQTQ3~sJ!HVcdLc%VL60X`?17u) z5$+PX7Xk&JM06acFSze1GU=L`M~A+x=Be$)9zXIstaqfw?)$6s{^<2X?d@-lsy`A1n^rsn$c83;AUNcd=cS!a2K{mDv(_J|~a?T6Yd~R3%HfXJjcI)*{p|v7$ z>RwxdZrqjS+t{yY=lqvFc#rqo%@OK<|A-!|@GGyLpql=1d5Zyalc&QmL2nOkplcaC MUHx3vIVCg!05t+)AOHXW literal 0 HcmV?d00001 diff --git a/Excel-custom-functions/web-worker/images/button32x32.png b/Excel-custom-functions/web-worker/images/button32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..e2efdb8d00e081133d568031c5f8bcf0be0901ce GIT binary patch literal 484 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0eMM8K~z{r?U%7i z13?r;1A-8+va(8LWo6|DSlJ3zsZt5H16Edo-(YLyH`q*J6-Z@eWo2b62!bH!y*p0~ z>z(YIWY#JN4$JJ^_coBt%w(`;WkTGAmvG1K{1YK=!)y2fzu-H(f?Jm8i4ZqofUl4b zZui;*sh200qUkD zcEXJ$#8b$Pg+;t_%=`R6&+uFC(c0TLwXA7@hS{UV8v;*g-)dc{bp1gT^QJ2C$2Iyk9QPgHCT&r^Zo^W&G-~?8KO!|u zTPO2tX8U+v)jRMrv4Zzs<1NnP6Sl59oai}G;oSGb#viz^_+4_kmeyA1IhEtw`NP)( ztXKN|U_0l%OX~3-mKu$PuQfLNdfbwF_(xz5PrajV#oRxdrlJ)3Xf4pldR^E~jQKZUsic z76HxdJ~5@#vlpF~tRYTOwzExJ|Eyz|F3y?yXpgF$`eK>+lQ$k~D7`N8{QjZE6KZSk zoZG|x{&aeuY~!58?CWMfv)C{CuF3r2t8Kh>&u(Zuk$G1$)ztTzbMTz|Z2E_;=I%KA z$@<()zMI=li)~pSF#C3;ug0%m=MHK8)thrVxk5*}cin;cKw-3YYRD_j!Gqx-ld<=^3P#!M1^j)snkyAP<^Sm(^0K&Chp@>{_gSm=;7?h(_6gb z`32%;NA1zynZI$GWYvTZ$JSmws6O?J!^7U-?()jK1AKPc%h|c}e?*y9Mg{YW-z(Vq zW6y`gh{?}ezfO3VyFbi#enfd4|C&!q9jl7o?hW$(U1$4gE~mBl^%bf|V;?gcJdu4F zJ|TPEpDVlmt(84$cTDp{E$`cwYmePen0~3B+qL(J@P@0^$rkC8Wu{6TJ$K78qBOkk z_?q|mQ~o_$ByV(0HD6EbTb2I7u-}K~Y9|{J v*fP~~{!V%RmpmoUf-(j;e@I@s{F#5P{gh*@oXckd^DBd=tDnm{r-UW|>~`K> literal 0 HcmV?d00001 diff --git a/Excel-custom-functions/web-worker/images/icon-16.png b/Excel-custom-functions/web-worker/images/icon-16.png new file mode 100644 index 0000000000000000000000000000000000000000..b6509798aadcf9eb0e382bab24b3dc67de818729 GIT binary patch literal 1596 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!6#=yXs@#Xw?AV;#qHKHUqKdq!Zu_%?nF(p4K zRlzeiF+DXXH8G{K@MNkD0|RqeW=KRygs+cPa(=E}B1ny1MQ#C5Hv@x>eMLcHa&~Ho zLQ-maW}dCm``!DM6f#q6mBLMZ4SWlnQ!_F>s)|yBtNcQetFn_VQY3>#8yZ_Em|N-@ znp#>Indm4O85o-B8(8Wan&=uBS{Ybc85k-+ffCTRqLehNAQv~NT|l0#QbtKhft9{~ zd3m{Bxv^e;QM$gNrKP35fswwEkuFe$ZgFK^Nn(X=Ua>OF1ees}t-3#_`hBq$Z(46Le)Ln;eW z^@CE2^Gl18f$@>14ATq@JNy=b6armiBkFOx%nuOw0|9EzK=pdOh=sOA_;vQ(<;z0_}$CHO8yg%DE^tu_V7JBtJg~ zmI?wg@=NlIGx7@*oSi|jZmysao|%`DUtX*UiYAD!T~doO%TiO^it=+6z~O9_iNy`X z`5&S`h1~Gd2Rce0lvt1w4@?M{B0)@eRseF~nJG07n1hOdS;gz?%1QF! zNj{#Qi51`9#YzfKSn=oo|9W)?217PhR>KB{%eS}Z|L5lB{?E>#u;IkvcK-jy4vfOg zQVbjlGv+ZU*nNF}e}B5piBtdo{k5LkIdkUB#_7|iAG~>UCS!)L+Tx8HKgupxVieM9 z;=ph)hmrG+qw#;SfJUnm*Ax~QmN$qQbaZt!^)fStg@u_ae3f7FKq5f(L`_@z`FV|^ zjX&(`{xGckeTwDEPbQ5698Y|blai8l)c!W}c*HDln&D_A15<(PF*A-M1|p>s*gIT~ zn1*Doc||WTP4AD)uh@2z0hc!;5D1oQ7ln-cB=>@Ff`rX+&w41;T!*&zXBV*Cz?$Vk!Iq)rRwX%^5-j9%af=3%!||AYENwP@joEdEZfX{dHR}v2RPpx>}6+lRN#BuRKcQm0YhU2PgTe~DWM4fV}M0Q literal 0 HcmV?d00001 diff --git a/Excel-custom-functions/web-worker/images/icon-32.png b/Excel-custom-functions/web-worker/images/icon-32.png new file mode 100644 index 0000000000000000000000000000000000000000..dcf56db7089a10edc61a0914be2af6736c8c676c GIT binary patch literal 2386 zcmbVOX;2es8t#w~5{5vyBA3zx&_zkoImjg-fq(=FA_j;fD+x&>QF53B2?{%Mh=3@& z=&Inch^2TUIO72_Gs>}`Fs_c*Dkvg~sGuSWjvP*-;_eS?YHPcytH1B-=Xu}fy{f*# z=%|GROBYK300^RRVGQyGr(PTu08p5$h$Lj=Yz&nemui!Z>2f^`2$b3+7!;}HE8!Se zuFP0-3HAp7^jeifYLtp2`3kL?DxbnoO==y&1_1vBCY@Zd8a9GS@Jf{?fc*0O&ty=g z3?Rq*i6OBr1Wr+fuhYXz*F{Mb>sBjxO7en0(BH&I45(qF95ks@H3q&Zfc()eA6ZWw z)5zdQh;elQ`I9KAI2sJm>S552%BCpjOfJabQR#j>E`#L@G9Wse2JvWg76qd7As!#1 zgP$KV;!Uqi=En%bKKnv;0pt{;QOBpz($mwa=}f9tzmi7h@pv?dL1Qo|2!dkB&=}<= zipJnMZ9xbd6nd4;sM2b{DU0$XZJIHFj41sSf?6jQe=)2vd`=XSGMY)QqtU4lO|71a z>m%A=jDi0nqogF$*_8SZ>tnC0cFj zbQeUYXpLG!idF}PgiKYP1O6#qrBQ0r4L(z4`V_Sg)~nXS$}qiF4SvisU-cCY|6BZ@ z_{#q`e>6lCZK_%Rt9ho6kdB;Mei;R1^JSP|4KhJ`WKNU&xk(?p< zmLEpzf`USrMP&qsR8qPeME$1Q&*kAxx&K*hynCoXQDAaGNHAFRbmcq z17NnP>Hd%FdpsqU#*&XU==W=1`)9r1-ZT8e6?*289-@T6Z>%bzU^vJ8sK#m?#=QbCPbk~`Rkez-iyA63Aq zsM~-70XVj!)WacEJG6guH%;f5T9ooze%!%6?84n@mEPxY?TKqd3)ckiiym#4YCX0j zlskU=&Hf7Sb)#>q8%_p#+PD!jM+3XFp19r4?4Gm!gqdc7H)7}KKd-%XUP2?P_h!*s zo8tM!FIlebr+z8{?@d@7V4Uh9_3q~0E%WX4Mo*%vDqje#x2)flub?N~2kHpdhr$V4 zU!m+TK*a)o2Uo7F-kaw{U#Y^5N%Ar_ZQSMJv{mku^SoYGKHDJ_Renei8+&y$z;DT| zr@ojj?{-E(Wx*3ksaN!EzyA6whNd&>3|@M#eedkcX|>W<-8jB3@E;*W%!76#mg)~5aU+mhL#c4#Je4VMAooIGr zg*gR}Sz@xZDJP~u%ZRj`Y^<#yd*?X%>FGr?Y~mJxQ2mXTdL!Z4t;GK5y}28$BdV-} z&kAqV$HtLFFV{Ex4ZiC*H>I zOXcO{?~krHc`W(+BM}Gf=HT+pm$6+4nnhlAM-!;?TGvQU#4UYl{MOOZd|y*RMq^~S z@x#4=n=8WSZ;PsGI^VeUhn`?p;cPeSVf#TTu6M}#@0(ka22T11&T*JzKAKy+=S88A zoJHCc2|l>JW_!3<5%y`2`<_{)N&8YypR5fRtiM3}kD$?m@9?AT_4EiEs! z@z^D_dyLa2#iI>|Mz@|jC3rtVZ^u#3gm;lFQ~S1}(}kRx#k;@`yAfPTU~j`!FA07} zN3HlBy>&>P+j8Z}aIP<(H7=Fa7y0lglD_z>?=Pyy(Eg=@VXU>-GXhgJn6t E1JVSZtpET3 literal 0 HcmV?d00001 diff --git a/Excel-custom-functions/web-worker/images/icon-80.png b/Excel-custom-functions/web-worker/images/icon-80.png new file mode 100644 index 0000000000000000000000000000000000000000..5e63769d8e0f21f7ba1dc81cbc6070d901b4d8ac GIT binary patch literal 4836 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 literal 0 HcmV?d00001 diff --git a/Excel-custom-functions/web-worker/manifest-localhost.xml b/Excel-custom-functions/web-worker/manifest-localhost.xml new file mode 100644 index 000000000..85aebc350 --- /dev/null +++ b/Excel-custom-functions/web-worker/manifest-localhost.xml @@ -0,0 +1,162 @@ + + + + + + + 91dd5cf9-9c42-4425-8b1e-8a5d90cca373 + + + 1.0.0.0 + Microsoft + en-US + + + + + + + + + + + + + + + + + + + + + + + ReadWriteDocument + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <!-- Description of the Getting Started callout. resid points to a LongString resource --> + <Description resid="OEP.GetStarted.Description" /> + + <!-- Point to a url resource which details how the add-in should be used. --> + <LearnMoreUrl resid="OEP.GetStarted.LearnMoreUrl" /> + </GetStarted> + + <!-- Function file is a HTML page that includes the JavaScript where functions for ExecuteAction will be called. + Think of the FunctionFile as the code behind ExecuteFunction. --> + <FunctionFile resid="OEP.SharedRuntime.Url" /> + + <!-- PrimaryCommandSurface is the main Office Ribbon. --> + <ExtensionPoint xsi:type="PrimaryCommandSurface"> + <!-- Use OfficeTab to extend an existing Tab. Use CustomTab to create a new tab. --> + <OfficeTab id="TabHome"> + <!-- Ensure you provide a unique id for the group. Recommendation for any IDs is to namespace using your company name. --> + <Group id="OEP.Group1"> + <!-- Label for your group. resid must point to a ShortString resource. --> + <Label resid="OEP.Group1Label" /> + <!-- Icons. Required sizes 16,32,80, optional 20, 24, 40, 48, 64. Strongly recommended to provide all sizes for great UX. --> + <!-- Use PNG icons. All URLs on the resources section must use HTTPS. --> + <Icon> + <bt:Image size="16" resid="OEP.tpicon_16x16" /> + <bt:Image size="32" resid="OEP.tpicon_32x32" /> + <bt:Image size="80" resid="OEP.tpicon_80x80" /> + </Icon> + + <!-- Control. It can be of type "Button" or "Menu". --> + <Control xsi:type="Button" id="OEP.TaskpaneButton"> + <Label resid="OEP.TaskpaneButton.Label" /> + <Supertip> + <!-- ToolTip title. resid must point to a ShortString resource. --> + <Title resid="OEP.TaskpaneButton.Label" /> + <!-- ToolTip description. resid must point to a LongString resource. --> + <Description resid="OEP.TaskpaneButton.Tooltip" /> + </Supertip> + <Icon> + <bt:Image size="16" resid="OEP.tpicon_16x16" /> + <bt:Image size="32" resid="OEP.tpicon_32x32" /> + <bt:Image size="80" resid="OEP.tpicon_80x80" /> + </Icon> + + <!-- This is what happens when the command is triggered (E.g. click on the Ribbon). Supported actions are ExecuteFunction or ShowTaskpane. --> + <Action xsi:type="ShowTaskpane"> + <!-- Provide a url resource id for the location that will be displayed on the task pane. --> + <SourceLocation resid="OEP.SharedRuntime.Url" /> + </Action> + </Control> + </Group> + </OfficeTab> + </ExtensionPoint> + </DesktopFormFactor> + </Host> + </Hosts> + + <!-- You can use resources across hosts and form factors. --> + <Resources> + <bt:Images> + <bt:Image id="OEP.tpicon_16x16" DefaultValue="https://localhost:8080/images/icon-16.png" /> + <bt:Image id="OEP.tpicon_32x32" DefaultValue="https://localhost:8080/images/icon-32.png" /> + <bt:Image id="OEP.tpicon_80x80" DefaultValue="https://localhost:8080/images/icon-80.png" /> + </bt:Images> + <bt:Urls> + <bt:Url id="OEP.CustomFunctions.Script" DefaultValue="https://localhost:8080/functions.js" /> + <bt:Url id="OEP.CustomFunctions.Json" DefaultValue="https://localhost:8080/functions.json" /> + <bt:Url id="OEP.SharedRuntime.Url" DefaultValue="https://localhost:8080/home.html" /> + <bt:Url id="OEP.GetStarted.LearnMoreUrl" DefaultValue="https://go.microsoft.com/fwlink/?LinkId=276812" /> + </bt:Urls> + <!-- ShortStrings max characters==125. --> + <bt:ShortStrings> + <bt:String id="OEP.TaskpaneButton.Label" DefaultValue="Show WebWorker task pane" /> + <bt:String id="OEP.Group1Label" DefaultValue="WebWorker sample" /> + <bt:String id="OEP.GetStarted.Title" DefaultValue="WebWorker sample" /> + <bt:String id="OEP.CustomFunctions.NameSpace" DefaultValue="WebWorkerSample" /> + </bt:ShortStrings> + <!-- LongStrings max characters==250. --> + <bt:LongStrings> + <bt:String id="OEP.TaskpaneButton.Tooltip" DefaultValue="Click to Show a task pane" /> + <bt:String id="OEP.GetStarted.Description" DefaultValue="Your sample add-in loaded succesfully. Go to the HOME tab and click the 'Show WebWorker task pane' button to get started." /> + <bt:String id="OEP.TestFuncButton.Tooltip" DefaultValue="Test AppCmd button" /> + </bt:LongStrings> + </Resources> + </VersionOverrides> + <!-- End Add-in Commands Mode integration. --> +</OfficeApp> diff --git a/Excel-custom-functions/web-worker/manifest.xml b/Excel-custom-functions/web-worker/manifest.xml new file mode 100644 index 000000000..986f5591b --- /dev/null +++ b/Excel-custom-functions/web-worker/manifest.xml @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="UTF-8"?> +<OfficeApp + xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" + xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" + xsi:type="TaskPaneApp"> + + <!-- Begin Basic Settings: Add-in metadata, used for all versions of Office unless override provided. --> + + <!-- IMPORTANT! Id must be unique for your add-in, if you reuse this manifest ensure that you change this id to a new GUID. --> + <Id>91dd5cf9-9c42-4425-8b1e-8a5d90cca373</Id> + + <!--Version. Updates from the store only get triggered if there is a version change. --> + <Version>1.0.0.0</Version> + <ProviderName>Microsoft</ProviderName> + <DefaultLocale>en-US</DefaultLocale> + + <!-- The display name of your add-in. Used on the store and various places of the Office UI such as the add-ins dialog. --> + <DisplayName DefaultValue="PnP WebWorker sample" /> + <Description DefaultValue="PnP WebWorker sample" /> + + <!-- Icon for your add-in. Used on installation screens and the add-ins dialog. --> + <IconUrl DefaultValue="https://officedev.github.io/PnP-OfficeAddins/Excel-custom-functions/web-worker/images/icon-32.png" /> + <!--End Basic Settings. --> + <!--Begin TaskPane Mode integration. This section is used if there are no VersionOverrides or if the Office client version does not support add-in commands. --> + <Hosts> + <Host Name="Workbook" /> + </Hosts> + <Requirements> + <Sets> + <Set Name="SharedRuntime" MinVersion="1.1"/> + </Sets> + </Requirements> + <DefaultSettings> + <SourceLocation DefaultValue="https://officedev.github.io/PnP-OfficeAddins/Excel-custom-functions/web-worker/home.html" /> + </DefaultSettings> + <!-- End TaskPane Mode integration. --> + + <Permissions>ReadWriteDocument</Permissions> + + <!-- Begin Add-in Commands Mode integration. --> + <VersionOverrides xmlns="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="VersionOverridesV1_0"> + + <!-- The Hosts node is required. --> + <Hosts> + <!-- Each host can have a different set of commands. --> + <!-- Excel host is Workbook, Word host is Document, and PowerPoint host is Presentation. --> + <!-- Make sure the hosts you override match the hosts declared in the top section of the manifest. --> + <Host xsi:type="Workbook"> + <Runtimes> + <Runtime resid="OEP.SharedRuntime.Url" lifetime="long" /> + </Runtimes> + + <AllFormFactors> + <ExtensionPoint xsi:type="CustomFunctions"> + <Script> + <!-- For now, we still need to have Script URL until the real SharedApp support is ready --> + <SourceLocation resid="OEP.CustomFunctions.Script" /> + </Script> + <Page> + <SourceLocation resid="OEP.SharedRuntime.Url"/> + </Page> + <Metadata> + <SourceLocation resid="OEP.CustomFunctions.Json" /> + </Metadata> + <Namespace resid="OEP.CustomFunctions.NameSpace" /> + </ExtensionPoint> + </AllFormFactors> + + <!-- Form factor. Currently only DesktopFormFactor is supported. --> + <DesktopFormFactor> + <!--"This code enables a customizable message to be displayed when the add-in is loaded successfully upon individual install."--> + <GetStarted> + <!-- Title of the Getting Started callout. resid points to a ShortString resource --> + <Title resid="OEP.GetStarted.Title" /> + + <!-- Description of the Getting Started callout. resid points to a LongString resource --> + <Description resid="OEP.GetStarted.Description" /> + + <!-- Point to a url resource which details how the add-in should be used. --> + <LearnMoreUrl resid="OEP.GetStarted.LearnMoreUrl" /> + </GetStarted> + + <!-- Function file is a HTML page that includes the JavaScript where functions for ExecuteAction will be called. + Think of the FunctionFile as the code behind ExecuteFunction. --> + <FunctionFile resid="OEP.SharedRuntime.Url" /> + + <!-- PrimaryCommandSurface is the main Office Ribbon. --> + <ExtensionPoint xsi:type="PrimaryCommandSurface"> + <!-- Use OfficeTab to extend an existing Tab. Use CustomTab to create a new tab. --> + <OfficeTab id="TabHome"> + <!-- Ensure you provide a unique id for the group. Recommendation for any IDs is to namespace using your company name. --> + <Group id="OEP.Group1"> + <!-- Label for your group. resid must point to a ShortString resource. --> + <Label resid="OEP.Group1Label" /> + <!-- Icons. Required sizes 16,32,80, optional 20, 24, 40, 48, 64. Strongly recommended to provide all sizes for great UX. --> + <!-- Use PNG icons. All URLs on the resources section must use HTTPS. --> + <Icon> + <bt:Image size="16" resid="OEP.tpicon_16x16" /> + <bt:Image size="32" resid="OEP.tpicon_32x32" /> + <bt:Image size="80" resid="OEP.tpicon_80x80" /> + </Icon> + + <!-- Control. It can be of type "Button" or "Menu". --> + <Control xsi:type="Button" id="OEP.TaskpaneButton"> + <Label resid="OEP.TaskpaneButton.Label" /> + <Supertip> + <!-- ToolTip title. resid must point to a ShortString resource. --> + <Title resid="OEP.TaskpaneButton.Label" /> + <!-- ToolTip description. resid must point to a LongString resource. --> + <Description resid="OEP.TaskpaneButton.Tooltip" /> + </Supertip> + <Icon> + <bt:Image size="16" resid="OEP.tpicon_16x16" /> + <bt:Image size="32" resid="OEP.tpicon_32x32" /> + <bt:Image size="80" resid="OEP.tpicon_80x80" /> + </Icon> + + <!-- This is what happens when the command is triggered (E.g. click on the Ribbon). Supported actions are ExecuteFunction or ShowTaskpane. --> + <Action xsi:type="ShowTaskpane"> + <!-- Provide a url resource id for the location that will be displayed on the task pane. --> + <SourceLocation resid="OEP.SharedRuntime.Url" /> + </Action> + </Control> + </Group> + </OfficeTab> + </ExtensionPoint> + </DesktopFormFactor> + </Host> + </Hosts> + + <!-- You can use resources across hosts and form factors. --> + <Resources> + <bt:Images> + <bt:Image id="OEP.tpicon_16x16" DefaultValue="https://officedev.github.io/PnP-OfficeAddins/Excel-custom-functions/web-worker/images/icon-16.png" /> + <bt:Image id="OEP.tpicon_32x32" DefaultValue="https://officedev.github.io/PnP-OfficeAddins/Excel-custom-functions/web-worker/images/icon-32.png" /> + <bt:Image id="OEP.tpicon_80x80" DefaultValue="https://officedev.github.io/PnP-OfficeAddins/Excel-custom-functions/web-worker/images/icon-80.png" /> + </bt:Images> + <bt:Urls> + <bt:Url id="OEP.CustomFunctions.Script" DefaultValue="https://officedev.github.io/PnP-OfficeAddins/Excel-custom-functions/web-worker/functions.js" /> + <bt:Url id="OEP.CustomFunctions.Json" DefaultValue="https://officedev.github.io/PnP-OfficeAddins/Excel-custom-functions/web-worker/functions.json" /> + <bt:Url id="OEP.SharedRuntime.Url" DefaultValue="https://officedev.github.io/PnP-OfficeAddins/Excel-custom-functions/web-worker/home.html" /> + <bt:Url id="OEP.GetStarted.LearnMoreUrl" DefaultValue="https://go.microsoft.com/fwlink/?LinkId=276812" /> + </bt:Urls> + <!-- ShortStrings max characters==125. --> + <bt:ShortStrings> + <bt:String id="OEP.TaskpaneButton.Label" DefaultValue="Show WebWorker task pane" /> + <bt:String id="OEP.Group1Label" DefaultValue="WebWorker sample" /> + <bt:String id="OEP.GetStarted.Title" DefaultValue="WebWorker sample" /> + <bt:String id="OEP.CustomFunctions.NameSpace" DefaultValue="WebWorkerSample" /> + </bt:ShortStrings> + <!-- LongStrings max characters==250. --> + <bt:LongStrings> + <bt:String id="OEP.TaskpaneButton.Tooltip" DefaultValue="Click to Show a task pane" /> + <bt:String id="OEP.GetStarted.Description" DefaultValue="Your sample add-in loaded succesfully. Go to the HOME tab and click the 'Show WebWorker task pane' button to get started." /> + <bt:String id="OEP.TestFuncButton.Tooltip" DefaultValue="Test AppCmd button" /> + </bt:LongStrings> + </Resources> + </VersionOverrides> + <!-- End Add-in Commands Mode integration. --> +</OfficeApp> diff --git a/Excel-custom-functions/web-worker/package-lock.json b/Excel-custom-functions/web-worker/package-lock.json new file mode 100644 index 000000000..d2d49bfe5 --- /dev/null +++ b/Excel-custom-functions/web-worker/package-lock.json @@ -0,0 +1,161 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } + }, + "basic-auth": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", + "integrity": "sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ=" + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=" + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ecstatic": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-3.3.2.tgz", + "integrity": "sha512-fLf9l1hnwrHI2xn9mEDT7KIi22UDqA2jaCwyCbSUJh9a1V+LEUSL/JO/6TIz/QyuBURWUHrFL5Kg2TtO1bkkog==", + "requires": { + "he": "^1.1.1", + "mime": "^1.6.0", + "minimist": "^1.1.0", + "url-join": "^2.0.5" + } + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "follow-redirects": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", + "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==" + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-server": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.12.3.tgz", + "integrity": "sha512-be0dKG6pni92bRjq0kvExtj/NrrAd28/8fCXkaI/4piTwQMSDSLMhWyW0NI1V+DBI3aa1HMlQu46/HjVLfmugA==", + "requires": { + "basic-auth": "^1.0.3", + "colors": "^1.4.0", + "corser": "^2.0.1", + "ecstatic": "^3.3.2", + "http-proxy": "^1.18.0", + "minimist": "^1.2.5", + "opener": "^1.5.1", + "portfinder": "^1.0.25", + "secure-compare": "3.0.1", + "union": "~0.5.0" + } + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==" + }, + "portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "requires": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + } + }, + "qs": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==" + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, + "secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=" + }, + "union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "requires": { + "qs": "^6.4.0" + } + }, + "url-join": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", + "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=" + } + } +} diff --git a/Excel-custom-functions/web-worker/readme.md b/Excel-custom-functions/web-worker/readme.md new file mode 100644 index 000000000..6e31cb901 --- /dev/null +++ b/Excel-custom-functions/web-worker/readme.md @@ -0,0 +1,234 @@ +--- +page_type: sample +products: + - office-excel + - office-365 +languages: + - javascript +extensions: + contentType: samples + technologies: + - Add-ins + createdDate: 12/16/2020 1:25:00 PM +description: "This sample shows how to use web workers in custom functions to prevent blocking the UI of your Office Add-in." +--- + +# Custom function sample using web worker + +## Summary + +This sample shows how to use web workers in custom functions to prevent blocking the UI of your Office Add-in. + +## Features + +- Custom Functions +- Web workers + +## Applies to + +- Excel on Windows, Mac, and in a browser. + +## Solution + +| Solution | Author(s) | +| ----------------------------------------------- | --------- | +| Office Add-in Custom Function Using Web Workers | Microsoft | + +## Version history + +| Version | Date | Comments | +| ------- | ---------- | --------------- | +| 1.0 | 12-16-2020 | Initial release | + +## Disclaimer + +**THIS CODE IS PROVIDED _AS IS_ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.** + +--- + +## Scenario + +When using the shared runtime, custom functions block the UI of your Office Add-in when they run. If you have long-running custom functions, this can cause poor performance in your Office Add-in UI when the spreadsheet is calculated. For example, if someone has a table with thousands of rows, each of which is calling a long-running custom function, this can lead to the UI being blocked during a recalculation. + +You can unblock the UI by using web workers to do the calculations for your custom functions. + +## Run the sample + +You can run this sample in Excel in a browser. The add-in web files are served from this repo on GitHub. + +1. Download the **manifest.xml** file from this sample to a folder on your computer. +1. Open [Office on the web](https://office.live.com/). +1. Choose **Excel**, and then open a new document. +1. Open the **Insert** tab on the ribbon and choose **Office Add-ins**. +1. On the **Office Add-ins** dialog, select the **MY ADD-INS** tab, choose **Manage My Add-ins**, and then **Upload My Add-in**. + ![The Office Add-ins dialog with a drop-down in the upper right reading "Manage my add-ins" and a drop-down below it with the option "Upload My Add-in"](images/office-add-ins-my-account.png) +1. Browse to the add-in manifest file, and then select **Upload**. + ![The upload add-in dialog with buttons for browse, upload, and cancel. +](images/upload-add-in.png) +1. Verify that the add-in loaded successfully. You will see a **Web worker task pane** button on the **Home** tab on the ribbon. + +Now you can use the following custom functions: + +``` +=WebWorkerSample.TEST(2) +=WebWorkerSample.TEST_PROMISE(2) +=WebWorkerSample.TEST_ERROR(2) +=WebWorkerSample.TEST_ERROR_PROMISE(2) +=WebWorkerSample.TEST_UI_THREAD(2) +``` + +If you open the task pane you will see an animated bouncing ball. You can see the effect of blocking the UI thread by entering `=WebWorkerSample.TEST_UI_THREAD(50000)` into a cell. The bouncing ball will stop for a few seconds while the result is calculated. + +## Run the sample from Localhost + +You host the web server for the sample on your computer by following these steps: + +1. You need http-server to run the local web server. If you haven't installed this yet you can do this with the following command: + + ```console + npm install --global http-server + ``` + +2. Use a tool such as openssl to generate a self-signed certificate that you can use for the web server. Move the cert.pem and key.pem files to the webworker-customfunction folder for this sample. +3. From a command prompt, go to the web-worker folder and run the following command: + + ```console + http-server -S --cors . + ``` + +4. To reroute to localhost run office-addin-https-reverse-proxy. If you haven't installed this you can do this with the following command: + + ```console + npm install --global office-addin-https-reverse-proxy + ``` + + To reroute run the following in another command prompt: + + ```console + office-addin-https-reverse-proxy --url http://localhost:8080 + ``` + +5. Sideload the add-in using the the previous steps (1 - 7). Upload the `manifest-localhost.xml` file for step 6. + +## Details + +### Dispatch to web worker + +When a custom function needs to use a web worker, we turn the calculation into a job and dispatch it to a web worker. The **dispatchCalculationJob** function takes the function name and parameters from a custom function, and creates a job object that is posted to a web worker. For more details see the **dispatchCalculationJob** function in [functions.js](functions.js). + +```JavaScript + // Post a job to the web worker to do the calculation + function dispatchCalculationJob(functionName, parameters) { + var jobId = g_nextJobId++; + return new Promise(function(resolve, reject) { + // store the promise information. + g_jobIdToPromiseInfoMap[jobId] = {resolve: resolve, reject: reject}; + var worker = getOrCreateWebWorker(jobId); + worker.postMessage({ + jobId: jobId, + name: functionName, + parameters: parameters + }); + }); + } +``` + +### Web worker runs the job and returns the result + +The web worker runs the job specified in the job object to do the actual calculation. The web worker code is in a separate file in [functions-worker.js](functions-worker.js). + +The functions-worker.js will: + +1. Receive a message containing the job to run. +2. Invoke a function to perform the calculation. +3. Call **postMessage** to post the result back to the main thread. + +```JavaScript +self.addEventListener('message', + function(event) { + var data = event.data; + if (typeof(data) == "string") { + data = JSON.parse(data); + } + + var jobId = data.jobId; + try { + var result = invokeFunction(data.name, data.parameters); + // check whether the result is a promise + if (typeof(result) == "function" || typeof(result) == "object" && typeof(result.then) == "function") { + result.then(function(realResult) { + postMessage( + { + jobId: jobId, + result: realResult + } + ); + }) + .catch(function(ex) { + postMessage( + { + jobId: jobId, + error: true + } + ) + }); + } + else { + postMessage({ + jobId: jobId, + result: result + }); + } + } + catch(ex) { + postMessage({ + jobId: jobId, + error: true + }); + } + } +); + +``` + +Most of the previous code handles the error case and Promise case. + +### Process results from the web worker + +In [functions.js](functions.js), when a new web worker is created, it is provided a callback function to process the result. The callback function parses the data to determine the outcome of the job. It resolves or rejects the promise as determined by the job result data. + +```JavaScript + // create a new web worker + var webWorker = new Worker("functions-worker.js"); + webWorker.addEventListener('message', function(event) { + var data = event.data; + if (typeof(data) == "string") { + data = JSON.parse(data); + } + + if (typeof(data.jobId) == "number") { + var jobId = data.jobId; + // get the promise info associated with the job id + var promiseInfo = g_jobIdToPromiseInfoMap[jobId]; + if (promiseInfo) { + if (data.error) { + // The web worker returned an error + promiseInfo.reject(new Error()); + } + else { + // The web worker returned a result + promiseInfo.resolve(data.result); + } + delete g_jobIdToPromiseInfoMap[jobId]; + } + } + }); +``` + +## Copyright + +Copyright (c) 2020 Microsoft Corporation. All rights reserved. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information, see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +<img src="https://telemetry.sharepointpnp.com/officedev/samples/excel-custom-function-web-workers" />