I have a batch job in node.js that: copies files into a directory, does analysis on files, then removes files.
I would like to iterate over an array of jobs and use generators to pause execution until that batch job is complete before starting another job. Here is what I have so far:
const cars = ["toyota", "honda", "acura"];
function copyFilesAndRunAnalysis(car) {
return new Promise(function(resolve, reject) {
setTimeout(function() { // simulate some delay
resolve(); // control should return to generator here
}, 1000);
});
}
function* doCar(car) {
yield copyFilesAndRunAnalysis(car);
}
// BEGIN HERE
console.log('start here');
carBatch = doCar(cars[0]);
carBatch.next(); // confusion here!!!
carBatch.next(); // should this all be in a forEach loop?
What I'd like to do is have a forEach that loops over each car, does all the respective work in the copyFilesAndRunAnalysis method -- pausing until Promise.resolve() and then on to the next one. Trying forEach does not make anything run at all.
You do not use .value at js at Question. The .value of the next() object yielded by Generator would be the Promise returned from copyFilesAndRunAnalysis, where .then() could be chained to .next().value(), Array.prototype.shift() could be used to recursively call doCar until no items remain within original or copy of cars array.
const cars = ["toyota", "honda", "acura"];
let carsCopy = cars.slice(0);
function copyFilesAndRunAnalysis(car) {
return new Promise(function(resolve, reject) {
setTimeout(function() { // simulate some delay
resolve(car); // control should return to generator here
}, 1000);
})
}
function* doCar(cars) {
yield copyFilesAndRunAnalysis(cars);
}
// BEGIN HERE
console.log("start here");
carBatch = doCar(carsCopy.shift());
carBatch.next().value.then(function re(data) {
console.log(data);
return carsCopy.length
? doCar(carsCopy.shift()).next().value.then(re)
: "complete"
})
.then(function(complete) {
console.log(complete);
})
Note, the same process can be achieved utilizing Promise, recursion; without using a Generator function.
const cars = ["toyota", "honda", "acura"];
let carsCopy = cars.slice(0);
function copyFilesAndRunAnalysis(car) {
return new Promise(function(resolve, reject) {
setTimeout(function() { // simulate some delay
resolve(car); // control should return to generator here
}, 1000);
})
}
// BEGIN HERE
console.log("start here");
carBatch = copyFilesAndRunAnalysis(carsCopy.shift());
carBatch.then(function re(data) {
console.log(data);
return carsCopy.length
? copyFilesAndRunAnalysis(carsCopy.shift()).then(re)
: "complete"
})
// do stuff when all items within `cars` have been
// processed through `copyFilesAndRunAnalysis`
.then(function(complete) {
console.log(complete);
})
ES6 generators don't have anything to do with asynchronous execution. They provide usable mechanism for implementing async control flow in third-party code (particularly co).
It may be used like that
co(function* () {
console.log('start here');
for (let car of cars) {
yield copyFilesAndRunAnalysis(car);
}
console.log('end here');
});
co transforms wrapped generator function into a promise and doesn't make miracles. All asynchronous actions should be performed inside generator function.
Related
In an attempt to understand promises more clearly, i have been reading up a few very interesting articles on the same. I came across the following code which works perfectly for executing promises sequentially. But i am not able to understand how it works.
function doFirstThing(){
return new Promise(function(resolve,reject){
setTimeout(()=>{
resolve(1);
},1000)
})
}
function doSecondThing(res){
return new Promise(function(resolve,reject){
setTimeout(()=>{
resolve(res + 1);
},1000)
})
}
function doThirdThing(res){
return new Promise(function(resolve,reject){
setTimeout(()=>{
resolve(res + 2);
},1000)
})
}
promiseFactories = [doFirstThing, doSecondThing, doThirdThing];
function executeSequentially(promiseFactories) {
var result = Promise.resolve(); // this is the most problematic line
promiseFactories.forEach(function (promiseFactory) {
result = result.then(promiseFactory);// what is happening here ?
});
return result;
}
executeSequentially(promiseFactories)
I do understand that promises are executed as soon as they are created. For some reason i am not able to understand the flow of execution. Especially this following line:
var result = Promise.resolve()//and empty promise is created.
Please if somebody can help me understand how calling the promiseFactory method inside the 'then' method of the empty promise makes it execute sequentially, like so. Or is it because of the forEach loop ?
result = result.then(promiseFactory);
I tried replacing the 'forEach' with a 'map' function and still yielded the same result. i.e, the methods where executed sequentially.
Also, how is the value passed from one chained function to other ?
Any help or article/blog is highly appreciated.
You can image a Promise as a box with execution inside. As far as the promise is created, the execution starts. To get the result value, you have to open the box. You can use then for it:
Promise.resolve(5).then(result => console.log(result)); // prints 5
If you want to chain promises you can do it by opening the box one by one:
Promise.resolve(5)
.then(result => Promise.resolve(result + 1))
.then(result => Promise.resolve(result * 2))
.then(result => console.log(result)); // prints 12
This chaining makes the executions synchronous (one by one).
If you want to execute several promises asynchronously (you don't chain results), you can use Promise.all:
Promise.all([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)])
.then(result => console.log(result)); // prints [1,2,3]
In your case:
Promise.all(promiseFactories).then(result => console.log(result));
Another option how to work with promises is to await them:
(async ()=> {
var res1 = await Promise.resolve(5);
var res2 = await Promise.resolve(res1 + 1);
var res3 = await Promise.resolve(res2 * 2);
console.log(res3); // prints 12
})();
await works similar to then - it makes asynchronous execution to synchronous.
In your case:
async function executeSequentially(promiseFactories) {
for (const p of promiseFactories) {
const result = await p;
console.log(result);
}
}
Note: await packs a value into a Promise out of the box:
var res1 = await 5; // same as await Promise.resolve(5)
The executeSequentially method returns all the Promises one after each other. It happens to iterate over promiseFactory, but it could be written as:
function executeSequentially(promiseFactories) {
return doFirstThing()
.then(() => doSecondThing())
.then(doThirdThing() );
}
It is just the same. We are basically returning a Promise.
Now, however, we want to iterate over a collection of promises.
When iterating, we need to attach the current Promise to the previous with a then. But the forEach does not expose the next Promise -or the previous- in every iteration. And yet we still need it in order to keep chaining Promises one by one. Hence, the result 'hack':
function executeSequentially(promiseFactories) {
var result = Promise.resolve(); /*We need a thing that keeps yelling
the previous promise in every iteration, so we can keep chaining.
This 'result' var is that thing. This is keeping a Promise in every
iteration that resolves when all the previous promises resolve
sequentially. Since we don't have a Promise in the array
previous to the first one, we fabricate one out of 'thin air'
with Promise.resolve() */
promiseFactories.forEach(function (promiseFactory) {
result = result.then(promiseFactory); /* Here result is update
with a new Promise, with is the result of chaining `result`
with the current one. Since `result` already had all the previous ones,
at the end, `result` will be a Promise that depends upon all the
Promises resolution.*/
});
return result;
}
Now, there's also a syntax quirk that maybe is puzzling you:
result = result.then(promiseFactory);
This line is pretty much the same as the following:
result = result.then(resolvedValue => promiseFactory(resolvedValue));
Please if somebody can help me understand how calling the promiseFactory method inside the 'then' method of the empty promise makes it execute sequentially, like so. Or is it because of the forEach loop ?
First thing first, promiseFactory is a pretty bad name there. The method should be better written as follows:
function executeSequentially(promises) {
var result = Promise.resolve(); // this is the most problematic line
promises.forEach(function (currentPromise) {
result = result.then(currentPromise);// what is happening here ?
});
return result;
}
So:
how calling the currentPromise method inside the 'then' method of the empty promise makes it execute sequentially?
It makes execute sequentially because when you attach a Promise to another by then, it executes sequentially. Is a then thing, it is not at all related to the fact that we are iterating over Promises. With plain Promises outside an iteration it works pretty much the same:
Promise.resolve() // fake Promises that resolves instanly
.then(fetchUsersFromDatabase) // a function that returns a Promise and takes
// like 1 second. It won't be called until the first one resolves
.then(processUsersData) // another function that takes input from the first, and
// do a lot of complex and asynchronous computations with data from the previous promise.
// it won't be called until `fetchUsersFromDatabase()` resolves, that's what
// `then()` does.
.then(sendDataToClient); // another function that will never be called until
// `processUsersData()` resolves
It is always recommended to use Promise.all if you want such behaviour:
function doFirstThing() {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(1);
}, 1000)
})
}
function doSecondThing(res) {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(res + 1);
}, 1000)
})
}
function doThirdThing(res) {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(res + 2);
}, 1000)
})
}
let promiseFactories = [doFirstThing(2), doSecondThing(1), doThirdThing(3)];
Promise.all(promiseFactories)
.then(data => {
console.log("completed all promises", data);
})
To run it sequentially one after another:
function doFirstThing() {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(1);
}, 1000)
})
}
function doSecondThing(res) {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(res + 1);
}, 3000)
})
}
function doThirdThing(res) {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(res + 2);
}, 5000)
})
}
promiseFactories = [doFirstThing, doSecondThing, doThirdThing];
function executeSequentially(promiseFactories) {
promiseFactories.forEach(function(promiseFactory) {
promiseFactory(1).then((data) => {
console.log(data)
});
});
}
executeSequentially(promiseFactories);
If we lay out the foreach loop it will look like the following
function doFirstThing(){
return new Promise(function(resolve,reject){
setTimeout(()=>{
console.log(1);
resolve(1);
},1000)
})
}
function doSecondThing(res){
return new Promise(function(resolve,reject){
setTimeout(()=>{
console.log(2);
resolve(res + 1);
},2000)
})
}
function doThirdThing(res){
return new Promise(function(resolve,reject){
setTimeout(()=>{
console.log(3);
resolve(res + 2);
},3000)
})
}
Promise.resolve()
.then(doFirstThing())
.then(doSecondThing())
.then(doThirdThing());
I do understand that promises are executed as soon as they are created. For some reason i am not able to understand the flow of execution. Especially this following line:
var result = Promise.resolve()//and empty promise is created.
This is just to get hold of the promise chain's starting point. Here it is an already resolved promise. To better understand it you can use one of your promises to get hold of the promise chain like below.
let promiseFactories= [doSecondThing, doThirdThing];
let result = doFirstThing();
promiseFactories.forEach(function (promiseFactory) {
result = result.then(promiseFactory);
});
This will also work.
I have two variables where certain values needs to be fulfilled and then call a function. One of the variables get set from an onComplete call after an js-animation is finished. The other is called once a video-file is completed preloading. My problem is that I don't know which one that will be called first. Therefore I would like to check so that both values are fulfilled with a promise.
They both get their values set in two different callback functions.
I have this but I don't understand how to use the callbacks with Promise.
// Callback 1:
function nextSlide(event){
finishedAnim = true;
};
// Callback 2:
function handleNextFileComplete(event) {
nextVideoEl.src = nextVideo;
nextfileLoaded = "complete";
};
Promise.all([
]).then(() => {
slider.next();
});
One solution would be using promises instead of control variables. Let's say you have a function to start the animation and other to start loading the video file.
function startAnimation() {
return new Promise((resolve, reject) => {
// Start the animation and pass the onAnimationCompleted callback
function onAnimationCompleted(event) {
resolve();
}
});
}
function startLoadingVideo() {
return new Promise((resolve, reject) => {
// Start loading the video and pass the onVideoLoaded callback
function onVideoLoaded(event) {
resolve();
}
});
}
Now you can call both functions and use the function Promise.all() to handle the promises. The calling method would be something like:
let animationPromise = startAnimation();
let videoPromise = startLoadingVideo();
Promise.all([animationPromise, videoPromise])
.then(() => slider.next());
I realised that this beacame kind of complex situation.
First I have timer with this code:
TweenMax.delayedCall(7.3, delayCallComplete);
function delayCallComplete(event){
finished = true;
};
Then I have preloading of video with this code:
function loadNextVideo() {
var preloadNext = new createjs.LoadQueue(true);
preloadNext.addEventListener("fileload", handleNextFileComplete);
preloadNext.loadFile(nextVideo);
};
function handleNextFileComplete(event) {
nextVideoEl.src = nextVideo;
nextfileLoaded = "complete";
};
I want to check that both of these cases has happened before calling a function containing slider.next();.
I have a set of about 100 arguments that all take different amounts of time to run through a given function. Each is a brief animation on a page, animating a different part depending on the argument, and they take about 1-3 seconds each.
I checked this: Nested setTimeout alternative?
...but it only works when the subfunctions take the same amount of time,
I can collect the arguments in an array in the order they should go, i.e.:
args= [arg1, arg2, arg3, arg4...]
Currently my calls looks like this:
setTimeout(myfunction(arg1), 3000);
setTimeout(myfunction(arg2), 5000);
setTimeout(myfunction(arg3), 7500);
setTimeout(myfunction(arg4), 8500);...
I'd really like to be able to have code that says "when myfunction(arg1) is finished, wait 500 milliseconds and then execute myfunction(arg2), then when that is finished wait 500 ms and execute func3, etc."
I don't know how to incorporate that into either the running of the setTimeouts or the definition of myfunction().
Thank you.
Promises are a perfect way to chain async operations.
If you could consider changing the body of myFunction so that it returns a promise then you could chain those operation easily.
The body of myFunction would look like this
function myFunction(args, time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
// here you do your stuff
resolve(); // resolve the promise when it's done
}, time);
})
}
And you call it this way
var args = [
{ args: "", timeout: 100 },
{ args: "", timeout: 300 }
]
var promise = Promise.resolve();
args.forEach(function (animation) {
promise = promise
.then(myFunction.bind(null, animation.args, animation.timeout))
// ^ chaining promise so that they fire one after another
})
You can just schedule your next task in the callback of the previous setTimeout, like that:
var tasks = [
{ arg : "arg1", delay : 3000},
{ arg : "arg2", delay: 2000},
{ arg : "arg3", delay : 2500}
];
function myFunction(arg) {
console.log(new Date(),arg);
}
function schedule() {
var task = tasks.shift();
if(task) {
setTimeout(function() {
myFunction(task.arg);
if(tasks.length) schedule();
},task.delay);
}
}
schedule();
This code will call myFunction("arg1") in 3000ms, then myFunction("arg2") in +2000ms and then myFunction("arg3") in +2500ms.
Each time it will remove (shift) the first element of your "task list",
and then stop once it is empty.
Take a note that this code will mutate your tasks array (by removing the next task from it on an each iteration), so you won't be able to reuse it.
If that is a problem, just use an explicit index to address the next task:
function schedule(tasks,i) {
if(i<tasks.length) {
setTimeout(function() {
myFunction(tasks[i].arg);
if(i+1<tasks.length) schedule(tasks,i+1);
},tasks[i].delay);
}
}
schedule(tasks,0);
I think the easiest way to sort out this problem is a promise chain:
var args = [1, 2, 3, 4, 5, 6]
var i = 0;
function doStuff(arg) {
//do stuff
console.log(arg)
}
function getPromise(cb, arg, time){
return function() {
return new Promise(function(resolve){
setTimeout(function(){
cb(arg)
resolve()
}, time)
})
}
}
var promise_chain = Promise.resolve();
while (args[i]) {
promise_chain = promise_chain.then(getPromise(doStuff, args[i++], 500))
}
This code will generate a bunch of promises. Each one waits 500ms to resolve itself and execute next bunch of code. Hope this help.
I've been learning promises using bluebird for two weeks now. I have them mostly understood, but I went to go solve a few related problems and it seems my knowledge has fell apart. I'm trying to do this simple code:
var someGlobal = true;
whilePromsie(function() {
return someGlobal;
}, function(result) { // possibly even use return value of 1st parm?
// keep running this promise code
return new Promise(....).then(....);
});
as a concrete example:
// This is some very contrived functionality, but let's pretend this is
// doing something external: ajax call, db call, filesystem call, etc.
// Simply return a number between 0-999 after a 0-999 millisecond
// fake delay.
function getNextItem() {
return new Promise.delay(Math.random()*1000).then(function() {
Promise.cast(Math.floor(Math.random() * 1000));
});
}
promiseWhile(function() {
// this will never return false in my example so run forever
return getNextItem() !== false;
}, // how to have result == return value of getNextItem()?
function(result) {
result.then(function(x) {
// do some work ...
}).catch(function(err) {
console.warn("A nasty error occured!: ", err);
});
}).then(function(result) {
console.log("The while finally ended!");
});
Now I've done my homework! There is the same question, but geared toward Q.js here:
Correct way to write loops for promise.
But the accepted answers, as well as additional answers:
Are geared toward Q.js or RSVP
The only answer geared toward bluebird uses recursion. These seems like it's likely to cause a huge stack overflow in an infinite loop such as mine? Or at best, be very inefficient and create a very large stack for nothing? If I'm wrong, then fine! Let me know.
Don't allow you to use result of the condition. Although this isn't requirement -- I'm just curious if it's possible. The code I'm writing, one use case needs it, the other doesn't.
Now, there is an answer regarding RSVP that uses this async() method. And what really confuses me is bluebird documents and I even see code for a Promise.async() call in the repository, but I don't see it in my latest copy of bluebird. Is it in the git repository only or something?
It's not 100% clear what you're trying to do, but I'll write an answer that does the following things you mention:
Loops until some condition in your code is met
Allows you to use a delay between loop iterations
Allows you to get and process the final result
Works with Bluebird (I'll code to the ES6 promise standard which will work with Bluebird or native promises)
Does not have stack build-up
First, let's assume you have some async function that returns a promise whose result is used to determine whether to continue looping or not.
function getNextItem() {
return new Promise.delay(Math.random()*1000).then(function() {
return(Math.floor(Math.random() * 1000));
});
}
Now, you want to loop until the value returned meets some condition
function processLoop(delay) {
return new Promise(function(resolve, reject) {
var results = [];
function next() {
getNextItem().then(function(val) {
// add to result array
results.push(val);
if (val < 100) {
// found a val < 100, so be done with the loop
resolve(results);
} else {
// run another iteration of the loop after delay
setTimeout(next, delay);
}
}, reject);
}
// start first iteration of the loop
next();
});
}
processLoop(100).then(function(results) {
// process results here
}, function(err) {
// error here
});
If you wanted to make this more generic so you could pass in the function and comparison, you could do this:
function processLoop(mainFn, compareFn, delay) {
return new Promise(function(resolve, reject) {
var results = [];
function next() {
mainFn().then(function(val) {
// add to result array
results.push(val);
if (compareFn(val))
// found a val < 100, so be done with the loop
resolve(results);
} else {
// run another iteration of the loop after delay
if (delay) {
setTimeout(next, delay);
} else {
next();
}
}
}, reject);
}
// start first iteration of the loop
next();
});
}
processLoop(getNextItem, function(val) {
return val < 100;
}, 100).then(function(results) {
// process results here
}, function(err) {
// error here
});
Your attempts at a structure like this:
return getNextItem() !== false;
Can't work because getNextItem() returns a promise which is always !== false since a promise is an object so that can't work. If you want to test a promise, you have to use .then() to get its value and you have to do the comparson asynchronously so you can't directly return a value like that.
Note: While these implementations use a function that calls itself, this does not cause stack build-up because they call themselves asynchronously. That means the stack has already completely unwound before the function calls itself again, thus there is no stack build-up. This will always be the case from a .then() handler since the Promise specification requires that a .then() handler is not called until the stack has returned to "platform code" which means it has unwound all regular "user code" before calling the .then() handler.
Using async and await in ES7
In ES7, you can use async and await to "pause" a loop. That can make this type of iteration a lot simpler to code. This looks structurally more like a typical synchronous loop. It uses await to wait on promises and because the function is declared async, it always returns a promise:
function delay(t) {
return new Promise(resolve => {
setTimeout(resolve, t);
});
}
async function processLoop(mainFn, compareFn, timeDelay) {
var results = [];
// loop until condition is met
while (true) {
let val = await mainFn();
results.push(val);
if (compareFn(val)) {
return results;
} else {
if (timeDelay) {
await delay(timeDelay);
}
}
}
}
processLoop(getNextItem, function(val) {
return val < 100;
}, 100).then(function(results) {
// process results here
}, function(err) {
// error here
});
Just a quick question of clarifications: is JavaScript Promise asynchronous? I've been reading a lot of posts on Promise and async programming (namely ajax requests). If Promise is not async, how do we make it so?
For example, I have a function to wrap a function f with argument array args inside a Promise. Nothing about f inherently is async.
function getPromise(f, args) {
return new Promise(function(resolve, reject) {
var result = f.apply(undefined, args);
resolve(result);
});
}
To make this async, I read some SO posts and decided that the setTimeout is what a lot of people were recommending to make code non-blocking.
function getPromise(f, args) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
var r = f.apply(undefined, args);
resolve(r);
}, 0);
});
}
Would this approach with setTimeout work to make code non-blocking inside a Promise?
(Note that I am not relying on any third-party Promise API, just what is supported by the browsers).
I think you are working under a misunderstanding. JavaScript code is always* blocking; that is because it runs on a single thread. The advantages of the asynchronous style of coding in Javascript is that external operations like I/O do not require blocking that thread. The callback that processes the response from the I/O is still blocking though and no other JavaScript can run concurrently.
* Unless you consider running multiple processes (or WebWorkers in a browser context).
Now for your specific questions:
Just a quick question of clarifications: is JavaScript Promise asynchronous?
No, the callback passed into the Promise constructor is executed immediately and synchronously, though it is definitely possible to start an asynchronous task, such as a timeout or writing to a file and wait until that asynchronous task has completed before resolving the promise; in fact that is the primary use-case of promises.
Would this approach with setTimeout work to make code non-blocking inside a Promise?
No, all it does is change the order of execution. The rest of your script will execute until completion and then when there is nothing more for it to do the callback for setTimeout will be executed.
For clarification:
console.log( 'a' );
new Promise( function ( ) {
console.log( 'b' );
setTimeout( function ( ) {
console.log( 'D' );
}, 0 );
} );
// Other synchronous stuff, that possibly takes a very long time to process
console.log( 'c' );
The above program deterministically prints:
a
b
c
D
That is because the callback for the setTimeout won't execute until the main thread has nothing left to do (after logging 'c').
const p = new Promise((resolve, reject) => {
if (1 + 1 === 2) {
resolve("A");
} else {
reject("B");
}
});
p.then((name) => console.log(name)).catch((name) => console.log(name));
console.log("hello world");
Promise doesn't block the next lines while it's in pending state. So, it works asynchronously.
Your MDN reference was helpful. Thx.
If you run this, you should see
asynchronous output.
================================================================
asynchronous using "Promise"
const log = console.log;
//---------------------------------------
class PromiseLab {
play_promise_chain(start) {
//"then" returns a promise, so we can chain
const promise = new Promise((resolve, reject) => {
resolve(start);
});
promise.then((start) => {
log(`Value: "${start}" -- adding one`);
return start + 1;
}).then((start) => {
log(`Value: "${start}" -- adding two`);
return start + 2;
}).then((start) => {
log(`Value: "${start}" -- adding three`);
return start + 3;
}).catch((error) => {
if (error) log(error);
});
}
}
//---------------------------------------
const lab = new PromiseLab();
lab.play_promise_chain(100);
lab.play_promise_chain(200);
Output should be asynchronous something like:
Value: "100" -- adding one
Value: "200" -- adding one
Value: "101" -- adding two
Value: "201" -- adding two
Value: "103" -- adding three
Value: "203" -- adding three
================================================================
Synchronous using "MyPromise" (e.g. basic js code)
const log = console.log;
//---------------------------------------
class MyPromise {
value(value) { this.value = value; }
error(err) { this.error = err; }
constructor(twoArgFct) {
twoArgFct(
aValue => this.value(aValue),
anError => this.error(anError));
}
then(resultHandler) {
const result = resultHandler(this.value);
return new MyPromise((resolve, reject) => {
resolve(result);
});
}
catch(errorHandler) {
errorHandler(this.error());
}
}
//--------------------------------------
class MyPromiseLab {
play_promise_chain(start) {
//"then" returns a promise, so we can chain
const promise = new MyPromise((resolve, reject) => {
resolve(start);
});
promise.then((start) => {
log(`Value: "${start}" -- adding one`);
return start + 1;
}).then((start) => {
log(`Value: "${start}" -- adding two`);
return start + 2;
}).then((start) => {
log(`Value: "${start}" -- adding three`);
return start + 3;
}).catch((error) => {
if (error) log(error);
});
}
}
//---------------------------------------
const lab = new MyPromiseLab();
lab.play_promise_chain(100);
lab.play_promise_chain(200);
Output should be synchronous:
Value: "100" -- adding one
Value: "101" -- adding two
Value: "103" -- adding three
Value: "200" -- adding one
Value: "201" -- adding two
Value: "203" -- adding three