Jelajahi Sumber

* Async/Await demos

michael 5 tahun lalu
induk
melakukan
16ebfa97cd

+ 7 - 1
demo/Makefile

@@ -6,7 +6,7 @@ TARGETS=democomponents demobrowseconsole demoajax demoxhr restbridgeclient \
   chartjs_democustompoints chartjs_demopolararea promiseall promisestory1 \
   promisestory2 promisestory demodb demoload demorest fpcunitbrowsertest \
   sampleda webgl1 pdfbasic hotreload dynload bootstraptable fullcalendar \
-  jitsimeet opentok
+  jitsimeet opentok asyncmany asyncfetch asyncmanualpromise
 
 ifneq ($(SKIPWEBCOMPILER),1)
 TARGETS:=$(TARGETS) demowebcompiler
@@ -116,3 +116,9 @@ jitsimeet: ./jitsimeet/demojitsimeet.lpr
 	$(BROWSERP2JS) $<
 opentok: ./opentok/demoopentok.lpr
 	$(BROWSERP2JS) $<
+asyncmany: ./asyncawait/trymany.lpr
+	$(BROWSERP2JS) $<
+asyncfetch: ./asyncawait/tryfetch.lpr
+	$(BROWSERP2JS) $<
+asyncmanualpromise: ./asyncawait/manualpromise.lpr
+	$(BROWSERP2JS) $<

+ 6 - 0
demo/asyncawait/description.txt

@@ -0,0 +1,6 @@
+This example fetches 3 files, and waits for all 3 fetches to be completion
+using the TJSPromise.All() function.
+
+Since there are 3 promises, the result is an array with 3 results.
+
+

TEMPAT SAMPAH
demo/asyncawait/fpc.png


+ 13 - 0
demo/asyncawait/manualpromise.html

@@ -0,0 +1,13 @@
+<html>
+  <head>
+    <title>Manual promise demo</title>
+    <script type="application/javascript" src="manualpromise.js"></script>
+  </head>
+  <body>
+    <div id="pasjsconsole"></div>
+    <script type="application/javascript">
+     rtl.run();
+    </script>
+  </body>
+</html>
+  

+ 84 - 0
demo/asyncawait/manualpromise.lpi

@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="12"/>
+    <General>
+      <Flags>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <MainUnitHasTitleStatement Value="False"/>
+        <MainUnitHasScaledStatement Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <Title Value="manualpromise"/>
+      <UseAppBundle Value="False"/>
+      <ResourceType Value="res"/>
+    </General>
+    <CustomData Count="2">
+      <Item0 Name="PasJSPort" Value="0"/>
+      <Item1 Name="PasJSWebBrowserProject" Value="1"/>
+    </CustomData>
+    <BuildModes>
+      <Item Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <UseFileFilters Value="True"/>
+    </PublishOptions>
+    <RunParams>
+      <FormatVersion Value="2"/>
+    </RunParams>
+    <Units>
+      <Unit>
+        <Filename Value="manualpromise.lpr"/>
+        <IsPartOfProject Value="True"/>
+      </Unit>
+      <Unit>
+        <Filename Value="manualpromise.html"/>
+        <IsPartOfProject Value="True"/>
+      </Unit>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <Target FileExt=".js">
+      <Filename Value="manualpromise"/>
+    </Target>
+    <SearchPaths>
+      <UnitOutputDirectory Value="js"/>
+    </SearchPaths>
+    <Parsing>
+      <SyntaxOptions>
+        <AllowLabel Value="False"/>
+        <CPPInline Value="False"/>
+        <UseAnsiStrings Value="False"/>
+      </SyntaxOptions>
+    </Parsing>
+    <CodeGeneration>
+      <TargetOS Value="browser"/>
+    </CodeGeneration>
+    <Linking>
+      <Debugging>
+        <GenerateDebugInfo Value="False"/>
+        <UseLineInfoUnit Value="False"/>
+      </Debugging>
+    </Linking>
+    <Other>
+      <CustomOptions Value="-Jeutf-8 -Jirtl.js -Jc -Jminclude"/>
+      <CompilerPath Value="$(pas2js)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions>
+      <Item>
+        <Name Value="EAbort"/>
+      </Item>
+      <Item>
+        <Name Value="ECodetoolError"/>
+      </Item>
+      <Item>
+        <Name Value="EFOpenError"/>
+      </Item>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 34 - 0
demo/asyncawait/manualpromise.lpr

@@ -0,0 +1,34 @@
+Program manualpromise;
+
+uses browserconsole, JS, Web;
+
+function ResolveAfter2Seconds: TJSPromise;
+// returns immediately with a Promise,
+// which after 2 seconds gets resolved
+begin
+  Result:=TJSPromise.new(procedure(resolve, reject : TJSPromiseResolver)
+    begin
+    window.setTimeout(procedure
+      begin
+      resolve('resolved');
+      end,
+      2000); // wait 2 seconds
+    end);
+end;
+
+procedure AsyncCall; async;
+var s: string;
+begin
+  writeln('calling');
+  s := await(string,resolveAfter2Seconds());
+  // the await pauses this procedure returning to the caller
+  // when the Promise from resolveAfter2Seconds gets resolved 
+  // this procedure is continued
+  writeln(s); // expected output: 'resolved'
+end;
+
+begin
+  AsyncCall;
+  // calling AsyncCall returns immediately, while the Promise is waiting
+  writeln('called');
+end.

TEMPAT SAMPAH
demo/asyncawait/pas2js.png


+ 13 - 0
demo/asyncawait/tryfetch.html

@@ -0,0 +1,13 @@
+<html>
+  <head>
+    <title>fetch demo with async/await</title>
+    <script type="application/javascript" src="tryfetch.js"></script>
+  </head>
+  <body>
+    <div id="pasjsconsole"></div>
+    <script type="application/javascript">
+     rtl.run();
+    </script>
+  </body>
+</html>
+  

+ 84 - 0
demo/asyncawait/tryfetch.lpi

@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="12"/>
+    <General>
+      <Flags>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <MainUnitHasTitleStatement Value="False"/>
+        <MainUnitHasScaledStatement Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <Title Value="tryfetch"/>
+      <UseAppBundle Value="False"/>
+      <ResourceType Value="res"/>
+    </General>
+    <CustomData Count="2">
+      <Item0 Name="PasJSPort" Value="0"/>
+      <Item1 Name="PasJSWebBrowserProject" Value="1"/>
+    </CustomData>
+    <BuildModes>
+      <Item Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <UseFileFilters Value="True"/>
+    </PublishOptions>
+    <RunParams>
+      <FormatVersion Value="2"/>
+    </RunParams>
+    <Units>
+      <Unit>
+        <Filename Value="tryfetch.lpr"/>
+        <IsPartOfProject Value="True"/>
+      </Unit>
+      <Unit>
+        <Filename Value="tryfetch.html"/>
+        <IsPartOfProject Value="True"/>
+      </Unit>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <Target FileExt=".js">
+      <Filename Value="tryfetch"/>
+    </Target>
+    <SearchPaths>
+      <UnitOutputDirectory Value="js"/>
+    </SearchPaths>
+    <Parsing>
+      <SyntaxOptions>
+        <AllowLabel Value="False"/>
+        <CPPInline Value="False"/>
+        <UseAnsiStrings Value="False"/>
+      </SyntaxOptions>
+    </Parsing>
+    <CodeGeneration>
+      <TargetOS Value="browser"/>
+    </CodeGeneration>
+    <Linking>
+      <Debugging>
+        <GenerateDebugInfo Value="False"/>
+        <UseLineInfoUnit Value="False"/>
+      </Debugging>
+    </Linking>
+    <Other>
+      <CustomOptions Value="-Jeutf-8 -Jirtl.js -Jc -Jminclude"/>
+      <CompilerPath Value="$(pas2js)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions>
+      <Item>
+        <Name Value="EAbort"/>
+      </Item>
+      <Item>
+        <Name Value="ECodetoolError"/>
+      </Item>
+      <Item>
+        <Name Value="EFOpenError"/>
+      </Item>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 34 - 0
demo/asyncawait/tryfetch.lpr

@@ -0,0 +1,34 @@
+program tryfetch;
+
+{$mode objfpc}
+
+uses
+  browserconsole, JS, Web, SysUtils;
+
+procedure myFetch; async;
+var
+  response: TJSResponse;
+  myBlob: TJSBlob;
+  image: TJSHTMLImageElement;
+  objectURL: string;
+begin
+  try
+    response := await(window.fetch('pas2js.png'));
+
+    if not response.ok then
+      raise Exception.Create('HTTP error! status: '+str(response.status))
+    else begin
+      myBlob := await(response.blob());
+      objectURL := TJSURL.createObjectURL(myBlob);
+      image := TJSHTMLImageElement(document.createElement('img'));
+      image.src := objectURL;
+      document.body.appendChild(image);
+    end;
+  except
+    console.log(JSExceptValue);
+  end;
+end;
+
+begin
+  myFetch;
+end.

+ 13 - 0
demo/asyncawait/trymany.html

@@ -0,0 +1,13 @@
+<html>
+  <head>
+    <title>multiple fetch demo with async/await and TJSPromise.All</title>
+    <script type="application/javascript" src="trymany.js"></script>
+  </head>
+  <body>
+    <div id="pasjsconsole"></div>
+    <script type="application/javascript">
+     rtl.run();
+    </script>
+  </body>
+</html>
+  

+ 85 - 0
demo/asyncawait/trymany.lpi

@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="12"/>
+    <General>
+      <Flags>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <MainUnitHasTitleStatement Value="False"/>
+        <MainUnitHasScaledStatement Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <Title Value="trymany"/>
+      <UseAppBundle Value="False"/>
+      <ResourceType Value="res"/>
+    </General>
+    <CustomData Count="2">
+      <Item0 Name="PasJSPort" Value="0"/>
+      <Item1 Name="PasJSWebBrowserProject" Value="1"/>
+    </CustomData>
+    <BuildModes>
+      <Item Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <UseFileFilters Value="True"/>
+    </PublishOptions>
+    <RunParams>
+      <FormatVersion Value="2"/>
+    </RunParams>
+    <Units>
+      <Unit>
+        <Filename Value="trymany.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tryfetchmany"/>
+      </Unit>
+      <Unit>
+        <Filename Value="trymany.html"/>
+        <IsPartOfProject Value="True"/>
+      </Unit>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <Target FileExt=".js">
+      <Filename Value="trymany"/>
+    </Target>
+    <SearchPaths>
+      <UnitOutputDirectory Value="js"/>
+    </SearchPaths>
+    <Parsing>
+      <SyntaxOptions>
+        <AllowLabel Value="False"/>
+        <CPPInline Value="False"/>
+        <UseAnsiStrings Value="False"/>
+      </SyntaxOptions>
+    </Parsing>
+    <CodeGeneration>
+      <TargetOS Value="browser"/>
+    </CodeGeneration>
+    <Linking>
+      <Debugging>
+        <GenerateDebugInfo Value="False"/>
+        <UseLineInfoUnit Value="False"/>
+      </Debugging>
+    </Linking>
+    <Other>
+      <CustomOptions Value="-Jeutf-8 -Jirtl.js -Jc -Jminclude"/>
+      <CompilerPath Value="$(pas2js)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions>
+      <Item>
+        <Name Value="EAbort"/>
+      </Item>
+      <Item>
+        <Name Value="ECodetoolError"/>
+      </Item>
+      <Item>
+        <Name Value="EFOpenError"/>
+      </Item>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 67 - 0
demo/asyncawait/trymany.lpr

@@ -0,0 +1,67 @@
+program tryfetchmany;
+
+{$mode objfpc}
+
+uses
+  browserconsole, JS, Web, SysUtils, Types;
+
+function FetchBlob(url: string): TJSBlob; async;
+var
+  response: TJSResponse;
+begin
+  response := await(window.fetch(url));
+  if not response.ok then
+    raise Exception.create('HTTP error! status: '+str(response.status))
+  else
+    Result:=await(response.blob());
+end;
+
+function FetchText(url: string): string; async;
+var
+  response: TJSResponse;
+begin
+  response := await(window.fetch(url));
+  if not response.ok then
+    raise Exception.create('HTTP error! status: '+str(response.status))
+  else
+    Result:=await(response.text());
+end;
+
+procedure DisplayContent; async;
+var
+  coffee, tea, description: TJSPromise;
+  objectURL1, objectURL2, descText: String;
+  values: TJSValueDynArray;
+  image1, image2: TJSHTMLImageElement;
+  para: TJSHTMLElement;
+begin
+  try
+    coffee := FetchBlob('pas2js.png');
+    tea := FetchBlob('fpc.png');
+    description := FetchText('description.txt');
+
+    values := await(TJSValueDynArray,TJSPromise.all([coffee, tea, description]));
+
+    objectURL1 := TJSURL.createObjectURL(values[0]);
+    objectURL2 := TJSURL.createObjectURL(values[1]);
+    descText := string(values[2]);
+
+    image1 := TJSHTMLImageElement(document.createElement('img'));
+    image2 := TJSHTMLImageElement(document.createElement('img'));
+    image1.src := objectURL1;
+    image2.src := objectURL2;
+    document.body.appendChild(image1);
+    document.body.appendChild(image2);
+
+    para := TJSHTMLElement(document.createElement('p'));
+    para.textContent := descText;
+    document.body.appendChild(para);
+
+  except
+    writeln(JSExceptValue);
+  end;
+end;
+
+begin
+  DisplayContent;
+end.