How to check if there is already running function and if it is exist listen to this function result;
async function a() {
// wait 5 seconds and return foo = foo + 1;
// if A is already running await and return result of this running function A instead result;
}
If I translate the problem correctly, A returns a promise that is asynchronously settled. While the promise is pending, all calls to a wrapper function around A should return the currently pending promise.
If, however, A has not been called, or a previously return promise has been settled, A should be called again.
This can be achieved by chaining off the promise returned by A, using promise handlers to determine results are no longer pending, and have the wrapper function return the chained promise. This example code speeds up the process a little - four successive calls made to a 500ms apart get the same fulfilled value from A which is taking 2000ms to perform a mythical asynchronous task:
// promise a delay
const delay = ms => new Promise(resolve=>setTimeout(resolve, ms));
// async function A
let foo =0;
async function A() {
await delay( 2000); // 2 second example
return foo = foo + 1;
}
// Wrapper function a
const a=(()=>{
let pending = null;
const onfulfill = data => { pending = null; return data};
const onreject = err => { pending = null; throw err};
let a = ()=> pending || (pending = A().then(onfulfill, onreject));
return a;
})();
// and test
async function test() {
for( let i=1; i < 11; ++i) {
a().then( data=> console.log(`a() call ${i} fulfills with ${data}`));
await delay(500);
}
}
console.log(" a is a named function ", a.name == 'a')
test();
a is coded to be a named function which minimizes run time object creation by using the two parameter form of then and passing pre-compiled functions as handler arguments.
The catch handler re-throws the error for caller code to handle.
synchronous and asynchronous code don't mix well together. Calls to wrapper function a always receive a pending promise value in return.
Solution
You can create class that will be execute one flow (maximum) and await result if flow already running. It may looks something like that:
class OneThreadExecutor {
// Boolean variable which represents is task running right now
taskRunning = false;
// All Promise.resolve callbacks
listeners = [];
// Accept initial value
constructor(value = 0) {
this.value = value;
}
// Send [result = value + 1] after 5 sec
startNewTask = () => {
this.taskRunning = true;
setTimeout(() => {
this.taskRunning = false;
return this.sendResult();
}, 5000)
}
// Call all Promise.resolve callbacks, and pass [value + 1] to them
sendResult = () => {
for (const listener of this.listeners) {
listener(++this.value);
}
this.listeners = [];
}
// Main method that exec one task
getResult = () => new Promise(resolve => {
// Add callback to queue
this.listeners.push(resolve);
// Start new task if necessary
if (!this.taskRunning) this.startNewTask();
})
}
General concept
Async getResult method will register promise in class' queue. Any successfull task execution will send result to queue. Current task returns value + 1 on each getResult call and take 5 seconds for whole flow.
Usage
const a = new OneThreadExecutor(); // value = 0 by default
// will start task#1, 5 sec left till .then call, value = 1
a.getResult().then(...)
// 2.5 sec left, task#1 is already half progress, value = 2
setTimeout(() => {
a.getResult().then(...)
}, 2500)
Async/await
const a = new OneThreadExecutor(3); // let's set value = 3 initially
// will start task#1, 5 sec left till .then call, value = 4
a.getResult();
// wait till task#1 completed, 5 sec left, value = 5
const value = await a.getResult();
// will start task#2 bacause not task running, 5 sec left, value = 6
a.getResult();
Cons
In demo solution we already expect successful task execution, without error handling, so you may need to extend it for proper error catching during task execution.
var is_a_running = false;
function a() {
if (is_a_running == false) {
is_a_running = true
//do something
//after you have done the thing
is_a_running = false
}
else if (is_a_running == true){
result();
}
}
This is should help you
Related
I'm trying to add a sleep / delay function inside a js file, This one:
var webTest = function()
{
let regex = /^https?:\/\//;
let url = $('#list_urls').val().split('\n');
var xmlhttp = [], i;
var myObj2 = [], i;
for(let i = 0; i < url.length; i++)
{
(function(i) {
xmlhttp[i] = new XMLHttpRequest();
url[i] = url[i].replace(regex, '');
xmlhttp[i].open("GET", "https://website.com/API?key=<MY_API_KEY>&url="+url[i], false);
xmlhttp[i].onreadystatechange = function() {
if (xmlhttp[i].readyState === 4 && xmlhttp[i].status === 200) {
myObj2 = JSON.parse(xmlhttp[i].responseText);
document.getElementById("demo"+i).innerHTML = myObj2.results[1].categories;
}
};
xmlhttp[i].send();
})(i);
console.log(`The Server2: `+ myObj2);
}
}
I want this script to pause for 10 second and then again do work and then again pause for 10 second and do like this untill text length is greater thatn i in loop! My code works if i run for single time but it doesn't works if i run in loop because the website has rate limit in the api so that's why i'm trying to add a sleep function.
So what i've tried is await sleep(); method and also tried setTimeout method but it's not working as expected in sort it doesn't works at all with my code!
await sleep(); just doesn't works at all and displays msg like
Uncaught SyntaxError: await is only valid in async functions and async generators webTestfile.js:27
You can make use of ES6's async/await-feature!
To use await, it needs to be in a function/expression body declared async.
Basically, this will make your function be asynchronous, and make it wait for a Promise to be fulfilled. We make that Promise be fulfilled after a set delay using setTimeout().
Note that "after a set delay" does not mean "exactly after", it basically means "as early as possible after".
By doing this, the asynchronous function waits for the promise to be fulfilled, freeing up the callstack in the meantime so that other code can be executed.
The order of execution of this example is (simplified) as follows:
sleepingFunc() is placed on callstack
In iteration: await for Promise to be fulfilled, suspending this call 🡒 freeing up callstack
Place new calls on callstack
Eventually, Promise is fulfilled, ending await 🡒 place suspended call back on callstack
Repeat until sleepingFunc() finished
As you can see in step 3, if other calls take up more time than the delay, the suspended call will have to wait that extra time longer.
function sleep(ms) {
return new Promise(resolveFunc => setTimeout(resolveFunc, ms));
}
async function sleepingFunc() {
for (let i = 0; i < 5; ++i) {
console.log(i + " - from sleep");
await sleep(1000);
}
}
function synchronousFunc() {
for (let i = 0; i < 5; ++i) {
console.log(i + " - from sync");
}
}
sleepingFunc();
synchronousFunc();
This runs snippet runs one task every 1 second until the condition is satisfied, and then clears the timer.
const work = (i)=>{
console.log('doing work here ', i);
}
let counter = 0
const timer = setInterval(()=>{
if (timer && ++counter >= 10) {
clearInterval(timer)
}
work(counter);
}, 1000)
I’d just like to run an async function, have it wait till it has a return value, pass that return value to another async function and wash and repeat a few times. I’ve seen some examples but I’m struggling to make them work in test code. Forgive all the baseball context, but I had to have a little fun with this self-inflicted nose bleed.
I can't even make it work without passing return values in the attached code, feeling pretty stupid at the moment...
whosOnFirst(1)
.then(whatsOnSecond(2))
.then(iDunnosOnthird(3))
I'd like to see the syntax to have whosOnFirst(1) execute, pass a return value to whatsOnSecond() and pass it's return value to iDunnosOnthird(). Creating the desired output (less the spaces) referenced in the bottom of the snippet.
I really appreciate the help!
// Arbitrary timer with input/output parameters for async understanding;
function waitSec(callerName, pause) { //
console.log(`${callerName} called, waiting ${pause} second(s)...`)
setTimeout(function () {
console.log(`${callerName} sent ${pause + 1} in a return, and done!`)
return pause + 1; // delayed return value / adds 1 to input param
}, pause * 1000);
}
// Who's On First - run this first with an input param = 1
async function whosOnFirst(i) {
waitSec("who's on first", 1).then(result => {
return result;
})
}
// What's on Second - run after completion of whosOnFirst() using return for param
async function whatsOnSecond(i) {
waitSec("what's on second", i).then(result => {
return result;
})
}
// iDunno's on third - run after completion of whatsOnSecond(i) using return for param
async function iDunnosOnthird(i) {
waitSec("iDunno's on third", i).then(result => {
return result;
})
}
whosOnFirst(1)
.then(whatsOnSecond(2))
.then(iDunnosOnthird(3))
// CURRENT OUTPUT:
// who's on first called, waiting 1 second(s)...
// what's on second called, waiting 2 second(s)...
// iDunno's on third called, waiting 3 second(s)...
// who's on first sent 2 in a return, and done!
// what's on second sent 3 in a return, and done!
// iDunno's on third sent 4 in a return, and done!
// DESIRED OUTPUT:
// who's on first called, waiting 1 second(s)...
// who's on first sent 2 in a return, and done!
// what's on second called, waiting 2 second(s)...
// what's on second sent 3 in a return, and done!
// iDunno's on third called, waiting 3 second(s)...
// iDunno's on third sent 4 in a return, and done!
Working Solution
Your issue is that the waitSec is in a different context from the rest of the code. You need to lift it to the Promise context.
Then you have "promisified" code all the way down, and you can chain promises. Here it is working (further explanation below it):
// Arbitrary timer with input/output parameters for async understanding;
function waitSec(callerName, pause) { //
return new Promise(resolve => {
console.log(`${callerName} called, waiting ${pause} second(s)...`)
setTimeout(function () {
console.log(`${callerName} sent ${pause + 1} in a return, and done!`)
resolve(pause + 1); // delayed return value / adds 1 to input param
}, pause * 1000);
})
}
// Who's On First - run this first with an input param = 1
function whosOnFirst(i) {
return waitSec("who's on first", 1)
}
// What's on Second - run after completion of whosOnFirst() using return for param
function whatsOnSecond(i) {
return waitSec("what's on second", i)
}
// iDunno's on third - run after completion of whatsOnSecond(i) using return for param
function iDunnosOnthird(i) {
return waitSec("iDunno's on third", i)
}
whosOnFirst(1)
.then(whatsOnSecond)
.then(iDunnosOnthird)
.then(console.log)
Further Explanation
Your original implementation of waitSec always returns undefined to the caller:
// Arbitrary timer with input/output parameters for async understanding;
function waitSec(callerName, pause) { //
console.log(`${callerName} called, waiting ${pause} second(s)...`)
setTimeout(function () {
console.log(`${callerName} sent ${pause + 1} in a return, and done!`)
return pause + 1; // delayed return value / adds 1 to input param
}, pause * 1000);
// return undefined happens here
}
The return inside the setTimeout does not return to your calling code, because your code never calls this function. It is invoked by the JS timer code, asynchronously.
Returning values from async code using a callback
The way to communicate a result out of there to a caller is to either take a callback as a parameter to the outer function and call that callback in the async function, like this:
function waitSec({callerName, pause, callback}) {
console.log(`${callerName} called, waiting ${pause} second(s)...`)
setTimeout(function () {
console.log(`${callerName} sent ${pause + 1} in a return, and done!`)
callback(pause + 1); // delayed return value / adds 1 to input param
}, pause * 1000);
}
In which case you have the classic callback pattern of JS.
Using Promises, and why you might prefer them
Or, you return a Promise, and resolve it to return the value - as I demonstrated in the solution. For more about that, search for "how do I promisify a callback".
The benefit of doing it this way (with a Promise) is that Promises are composable, as demonstrated in the solution.
Promises are also await-able, so you can use async/await with Promise-returning functions.
You do not need to mark the Promise-returning functions as async.
If you mark a function as async, it returns a Promise, like this:
// A function marked async returns a Promise
async function simple() {
return 3
}
// Proof that it is a Promise
simple().then(console.log)
// The equivalent code explicitly returning a Promise - this is what `async` does
function simpleP(n = 0) {
return new Promise(resolve => resolve(n+1))
}
// Proof that it behaves the same
simpleP().then(console.log)
// Promise composition
simple()
.then(simpleP)
.then(console.log)
// Same functionality, using async/await
async function main() {
const num = await simple()
const res = await simpleP(num)
console.log(`${num} + 1 = ${res}`)
}
main()
Marking synchronous return functions async makes them composable with async code that actually needs a Promise to return a value. You can use it to lift your functions to the same async context and compose them.
// Synchronous function that is Promisified and composable
async function simple() {
return 3
}
To actually get a value out of an asynchronous function that takes a callback and provides its return via that, you must construct and return a Promise from your function, and then call the Promise resolve inside the callback that provides the value you want to communicate out.
function getDBRecordP(id) {
return new Promise((resolve, reject) =>
dbLib.get(id,
(err, result) => err ?
reject(err) :
resolve(result)))
}
In this case, you have to explicitly wire up the Promise machinery. This is pretty much the only time that you need to create and return a Promise.
What it is doing is wrapping a callback interface for you.
function getDBRecordP(id) {
return new Promise((resolve, reject) =>
dbLib.get(id,
(err, result) => err ?
reject(err) :
resolve(result)))
}
Notice in the callback example, you had to take a callback argument from the caller as a parameter, and then call that with the return value inside the callback that provides the value.
With the Promise machinery, you do take a callback argument, but it is not provided by the caller, it is provided by the Promise that you construct. And then you return the Promise to the caller.
The getDBRecordP function above is the essence of "how do I convert a function that takes a callback into a function that returns a Promise?".
The caller then passes in the callback to the the Promise.then() method.
So you have a machine that wraps the callback passing convention into a formal API that is composable, which callbacks are not.
The other aspect of the Promise machine is the .catch() method.
Whereas with callbacks, the convention has always been that a callback signature is (err, result), the Promise machine allows you to provide two callbacks - one for err and one for result.
Please utilize await keyword that is beautiful for async function. Your waitSec function should return a promise, also when you are resolving a promise, your value comes in .then((res)=> console.log(res)), use it for chaining like below:
// Arbitrary timer with input/output parameters for async understanding;
function waitSec(callerName, pause) { //
return new Promise((resolve, reject) => {
console.log(`${callerName} called, waiting ${pause} second(s)...`)
setTimeout(function() {
console.log(`${callerName} sent ${pause + 1} in a return, and done!`)
resolve(pause + 1); // delayed return value / adds 1 to input param
}, pause * 1000);
})
}
// Who's On First - run this first with an input param = 1
async function whosOnFirst(i) {
const resp = await waitSec("who's on first", 1);
return resp;
}
// What's on Second - run after completion of whosOnFirst() using return for param
async function whatsOnSecond(i) {
const resp = await waitSec("what's on second", i);
return resp;
}
// iDunno's on third - run after completion of whatsOnSecond(i) using return for param
async function iDunnosOnthird(i) {
const resp = await waitSec("iDunno's on third", i);
return resp;
}
whosOnFirst(1).then((firstResp) => {
whatsOnSecond(firstResp).then((secResp) => {
iDunnosOnthird(secResp).then((thirdResp) => {
console.log(thirdResp);
})
})
})
You can also use the values in chain like below with async/await:
// Arbitrary timer with input/output parameters for async understanding;
function waitSec(callerName, pause) { //
return new Promise((resolve, reject) => {
console.log(`${callerName} called, waiting ${pause} second(s)...`)
setTimeout(function() {
console.log(`${callerName} sent ${pause + 1} in a return, and done!`)
resolve(pause + 1); // delayed return value / adds 1 to input param
}, pause * 1000);
})
}
// Who's On First - run this first with an input param = 1
async function whosOnFirst(i) {
const resp = await waitSec("who's on first", 1);
return resp;
}
// What's on Second - run after completion of whosOnFirst() using return for param
async function whatsOnSecond(i) {
const resp = await waitSec("what's on second", i);
return resp;
}
// iDunno's on third - run after completion of whatsOnSecond(i) using return for param
async function iDunnosOnthird(i) {
const resp = await waitSec("iDunno's on third", i);
return resp;
}
let test = async() => {
var res1 = await whosOnFirst(1);
var res2 = await whatsOnSecond(res1);
var res3 = await iDunnosOnthird(res2);
console.log(res3);
}
test();
You need to await for each result like that:
async function main() {
const result1 = await whosOnFirst(1);
// whosOnSecond will not get called except after the whosOnFirst is done.
const result2 = await whosOnSecond(result1);
}
Here's how it's supposed to work:
function delay(milliseconds){
return new Promise((resolve)=>{
setTimeout(()=>{
resolve();
}, milliseconds);
});
}
async function test(){
console.log('no delay, yet');
await delay(1000);
console.log('After 1 second');
await delay(1000);
console.log('2 seconds have passed');
await delay(3000);
console.log('Oh look, 5 seconds have passed!');
}
test();
async functions await until a Promise is resolved, then go to the next block of code after the Promise, possibly awaiting again... and again. I admit I thought it was strange that an async function really runs the awaits synchronously, but the async function itself it asynchronous... meaning another function executed immediately after an executed async function is likely to return results before the async function executes.
In regards to your example:
class Counter{
constructor(increment = 1, initially = 0){
this.increment = increment; this.count = initially;
}
inc(){
return this.count += this.increment;
}
dec(){
return this.count -= this.increment;
}
}
function delay(milliseconds){
return new Promise((resolve)=>{
setTimeout(()=>{
resolve();
}, milliseconds);
});
}
const sec = new Counter;
function logCaller(callerName){
console.log(`${callerName} called, after ${sec.inc()} second(s)...`);
}
async function what(){
await delay(1000);
logCaller("who's on first");
await delay(1000);
logCaller("what's on second");
await delay(1000);
logCaller("iDunno's on third");
}
what();
Hello Stack Overflow community,
I come to you with a problem related to JS async/await. I am trying to call an async function and then log the array to where the async function pushes the results to the console. If I call it like so directly in the console:
console.log(Page.data) - I can see that it has results in it, but if it is called on click of a button it logs an empty array.
// It is a nested object so do not worry if you don't exactly understand where Page.data comes from
Page.data = []
async function f1() {
// Fetch JSON data
// Process data
// Pushes at some point to the Page.data array
}
async function f2() {
// Fetch JSON data
// Process data
// Pushes at some point to the Page.data array
}
async function f3() {
// Fetch JSON data
// Process data
// Pushes at some point to the Page.data array
}
async function load(loader) {
let fn = async function() {};
if(condition1) fn = f1;
else if(condition2) fn = f2;
else fn = f3;
// This is the line that makes me problems
// According to documentation async functions return a promise
// So why would the array in the case be empty?
// Since I am telling it to display after the function is done
await fn(loader).then(console.log(Page.data))
}
This is just a template of my code and logic. I hope that you can understand where I am going.
Your help will be much appreciated.
The await expression causes async function execution to pause until a Promise is settled (that is, fulfilled or rejected), and to resume execution of the async function after fulfillment. When resumed, the value of the await expression is that of the fulfilled Promise.
For instance (this is an MDN example with some added comments):
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
async function f1() {
// note that here, you are "awaiting" the RESOLVED RESULT of the promise.
// there is no need to "then" it.
var x = await resolveAfter2Seconds(10);
// the promise has now already returned a rejection or the resolved value.
console.log(x); // 10
}
f1();
So you would "await" your function, which would hold up the execution until the promise either resolves or rejects. After that line, you would run your console.log, and it would log as expected. Short answer, "remove the then".
I should add, if the result of the "awaited" function is not a promise, it is converted to a promise (so technically, there is no need to return a promise, it'll wrap up your returned value for you).
the problem is that you can use then with await for the same method, lets check some examples provided by MDN:
this is a working Promise using async/await:
let myFirstPromise = new Promise((resolve, reject) => {
setTimeout(function() {
resolve("Success!");
}, 250)
})
const functionCaller = async() => {
const result = await myFirstPromise
console.log("the result: ", result);
}
functionCaller();
what you are trying is:
let myFirstPromise = new Promise((resolve, reject) => {
setTimeout(function() {
resolve("Success!");
}, 250)
})
const functionCaller = async() => {
// you are not returning anything here... actually you are not doing anything with the response. despite it shows something, it is not sending any response
await myFirstPromise.then(console.log("something happened"))
}
// then this function doesn't really get a value.
functionCaller();
so what you need to do in your load call, is to change it like this:
async function load(loader) {
let fn = async function() {};
if(condition1) fn = f1;
else if(condition2) fn = f2;
else fn = f3;
return await fn(loader)
}
Lets say I have the following function:
let x = 1
function countForever() {
setTimeout(function() {
console.log(x)
x = x +1
countForever()
});
}
We also have an object which contains an EventEmitter called e. e has a state, and if that state doesn't equal 3, we wish to kill our function. We can achieve this with the following:
let x = 1
function countForever() {
if (e.state != 3) return
setTimeout(function() {
console.log(x)
x = x +1
countForever()
});
}
This works. However my real, non example function has a lot more steps in it, and I've found myself continually if checking the state, 8-10x through the function.
Given e is an EventEmitter I would like to catch these changes when the state changes and kill the function. Luckily, e already has an event we can listen for:
e.on('state_changed' , function(new_state) {
// Kill countForever
})
How do I stop execution of this function from outside of its scope?
EDIT: I don't know why I wrote a sample function with a setTimeout, it seems I've been quite misleading. Here's a better one:
async function functionToKill() {
if (e.state != 3) return
thing1 = await functionThatTakesALongTime()
if (e.state != 3) return
thing2 = await secondFunctionThatTakesALongTime()
if (e.state != 3) return
thing3 = await thirdFunctionThatTakesALongTime()
//.....
if (e.state != 3) return
thing10 = await tenthFunctionThatTakesALongTime()
}
// e is an event emitter
e.on('state_changed' , function(new_state) {
// Kill/interrupt functionToKill
})
Effectively within the function I'm continually checking for the state over and over and returning if it's changed. I don't feel this is clean, and would like to do the equivalent of a return from an external call triggered by an eventEmitter
You don't give us a whole lot to go on in your sample function, but here's an idea with that code. You use a master promise that when rejected causes your sequence of await operations to abort:
// create deferred object so it can be rejected externally
Promise.Deferred = function() {
if (!(this instanceof Promise.Deferred)) {
return new Promise.Deferred();
}
let p = this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
this.then = this.promise.then.bind(p);
this.catch = this.promise.catch.bind(p);
if (this.promise.finally) {
this.finally = this.promise.finally.bind(p);
}
}
// shared promise, when rejected our function stops advancing to more operations
let killPromise = new Promise.Deferred();
function raceKill(p) {
return Promise.race(killPromise, p);
}
async function functionToKill() {
try {
thing1 = await raceKill(functionThatTakesALongTime());
thing2 = await raceKill(secondFunctionThatTakesALongTime());
thing3 = await raceKill(thirdFunctionThatTakesALongTime());
//.....
thing10 = await raceKill(tenthFunctionThatTakesALongTime());
} catch(e) {
// perhaps handle kill errors separately from actual function rejection errors
}
}
// e is an event emitter
e.on('state_changed' , function(new_state) {
// Kill/interrupt functionToKill
killPromise.reject(new Error("state_changed"));
})
This structure with Promise.race() has a bit of an advantage in that it doesn't even wait for functionThatTakesALongTime() to finish before aborting (when your pseudo-code would have been able to check e.state). It aborts immediately when you reject killPromise. That other asynchronous operation isn't magically cancelled. It will still do what it was going to do, but your functionToKill() won't wait around for it.
With actual code, there are probably more elegant ways to do this than using shared scope variables like killPromise, passing parameters, sharing something as object properties, etc... But, hopefully this shows you the general idea.
kill countForever? you can save the return value of setTimeout function with a variable such as timer, then clearTimeout(timer) when state_changed event fired. I don`t know if what I understand is right?
I have a function that returns Promise
let processWork = function () {
return new Promise(resolve => {
console.log('- internal: start')
// just wait 200ms for example
let future = new Date(new Date().getTime() + 200)
while (future > new Date()) {}
console.log('- internal: done')
resolve()
})
}
I call it and use then function to change variable to break endless while but not work
let doing = false
let done = false
while (!done) {
if (doing) {
continue
}
console.log('Starting work')
doing = true
processWork()
.then(() => {
console.log('Finished')
done = true
})
}
I get output
Starting work
- internal: start
- internal: done
and my code's still running forever.
My question is why then function not running in this case.
It is not true that a promise will somehow get resolved while a busy loop is being executed. As long as a loop is executing no other JavaScript will execute (excluding web workers). The following loop will always execute the continue statement in every iteration and will never finish.
let doing = false
let done = false
while (!done) {
if (doing) {
continue
}
// ...
}
No promise could help interrupt this loop, but in your case, there is not even a promise since processWork never gets executed.
If processWork would get executed, the loop in the promise constructor callback will lock up the browser until the target time arrives: no other JavaScript gets executed during that delay. This defeats the purpose of promises: they are intended not to lock up the browser and allow the execution of other code while the promise is still pending.
So, do it like this:
let processWork = function () {
return new Promise(resolve => {
console.log('- internal: start delay of 200ms')
// just wait 200ms for example, but don't stop execution of other code
setTimeout(resolve, 200);
})
}
console.log('Starting work')
processWork().then(() => {
console.log('Promise resolved. Finished');
});
console.log('Waiting for promise to resolve...');
console.log('In the meanwhile let\'s calculate 10!');
let fact = 1;
for (let i = 1; i <= 10; i++) {
fact *= i;
}
console.log('10! = ', fact);