async-await-2.php
<?php
// BLP 2023-02-25 - use new approach
// async-await-2.php
// Demo showing how to use an async function and await.
// Use my mini framework to make thing easier. Documentation is avaliable at:
// https://github.com/bartonlp/site-class
$_site = require_once(getenv("SITELOADNAME"));
ErrorClass::setDevelopment(true);
$S = new $_site->className($_site); // $S gives access to my framework.
// This is the target of the 'fetch' calls in the 'async function'
if($_POST['page'] == 'sql') {
$sql = $_POST['sql'];
$rows = [];
// do a mysql query and then fetch the rows
$S->sql($sql);
while($row = $S->fetchrow('assoc')) {
$rows[] = $row;
}
// return the rows as json
$rows = json_encode($rows);
echo $rows;
exit();
}
// Get the source file to display
$file = escapeltgt(file_get_contents("async-await-2.php"));
// This is the JavaScript
$S->h_script = <<<EOF
<!-- Get the syntaxhightlighter code and the theme.css -->
<script src="https://bartonphillips.net/js/syntaxhighlighter.js"></script>
<link rel='stylesheet' href="https://bartonphillips.net/css/theme.css">
<script>
// We are using jQuery. This is the 'ready' function which in the includes/header.i.php file.
$(function() {
// The display file button
$("button").on("click", function() {
$("#fileinfo").css("display", "block");
});
// The async function that does the work. It takes an array of sql statements
async function getSql([...sql]) {
// set up the object for the 'fetch'. We do posts
let opt = {
body: "",
method: 'post',
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
};
let url = 'async-await-2.php';
let ret = [];
for(let i=0; i < sql.length; ++i) {
// do the fetch and parse the json
opt.body = 'page=sql&sql=' + sql[i];
// Here is what we do:
// let tmp = await fetch(url, opt);
// tmp = tmp.json();
// ret.push(tmp);
ret.push((await fetch(url, opt)).json());
}
return ret; // an array
};
// call 'getSql' with three sql statements
getSql(["select 4*5", "select curtime() as data", "select * from barton.tracker limit 3"])
.then((data) => Promise.all(data)) // What we get is an array of promises
.then(data => {
// Display each in the div
let disp = '';
for(let i=0; i < data.length; ++i) {
disp += display(data[i]);
}
$("#sql").html(disp);
})
.catch(err => console.log("ERR:", err)); // Catch any errors
// Take appart the returned rows
function display(data) {
let disp = '';
for(let v of data) {
console.log("v:", v);
for(let [k, vv] of Object.entries(v)) {
disp += `\${k}: \${vv}<br>`;
}
}
disp += "<br>";
return disp;
};
});
</script>
EOF;
$S->css = <<<EOF
#fileinfo {
display: none;
}
button {
font-size: 1rem;
padding: .2rem;
border-radius: .2rem;
margin-bottom: 20px;
}
#sql {
border: 1px solid black;
padding: .5rem;
display: table-cell;
}
EOF;
$S->banner = "<h1>async-await-2</h1>";
// Get the top and bottom part of the display.
[$top, $footer] = $S->getPageTopBottom();
echo <<<EOF
$top
<button>Display the File</button>
<div id="fileinfo">
<p><b>async-await-2.php</b></p>
<pre class='brush: php'>
$file
</pre>
</div>
<p>This is the results from three <i>sql</i> calls via <i>fetch</i> in an <i>async function</i>
with <i>await</i> (select 4*4; select currentime() as date; select * from barton.tracker limit 2).
The three <i>sql</i> statements are returned in an array. As a result
the first <i>then</i> needs to do a <i>Promise.all(data)</i> and send it to the second <i>then</i>.
You can review the code by clicking on the button above.</p>
<div id="sql"></div>
$footer
EOF;
This is the results from three sql calls via fetch in an async function with await (select 4*4; select currentime() as date; select * from barton.tracker limit 2). The three sql statements are returned in an array. As a result the first then needs to do a Promise.all(data) and send it to the second then. You can review the code by clicking on the button above.