Callbacks Exercise Javascript - javascript

I have been exercising callbacks and I got this exercise that I have been struggling with the syntax. Here is my code:
function wash(callback) {
setTimeout(function() {
console.log('wash');
callback();
}, 3000);
}
function dry(callback) {
setTimeout(function() {
console.log('dry');
callback();
}, 2000);
}
function fold(callback) {
setTimeout(function() {
console.log('fold');
callback();
}, 1000);
}
doLaundry([wash, dry, fold]);
Invoking the doLaundry([wash,dry,fold]) is supposed to print out the following:
wash dry fold Done!
by calling this function (needs work)
function doLaundry() {
// Call functions
}
I tried this and it was close but the syntax is wrong or uneeded:
function doLaundry(actions, callback) {
actions.forEach((item, index) => {
wash(item, (error) => dry(item, (error) => fold(item, (error) => {})));
});
}
I'm really confused how to implement the doLaundry() with callback after checking out other simple tutorials. Any suggestions how to approach this?

Since the functions don't need to be asynchronous, I think you're making this a lot more complicated than it needs to be. Just iterate through the array of actions (functions) and call them. Then log Done at the end.
function wash() {
console.log('wash');
}
function dry() {
console.log('dry');
}
function fold() {
console.log('fold');
}
const doLaundry = (fns) => {
fns.forEach(fn => {
fn();
});
console.log('Done!');
}
doLaundry([wash, dry, fold]);
Or, if you must stick with the asynchronous functions, you can build up the callback chain starting from the last one in the chain and going backwards with reduceRight:
function wash(callback) {
setTimeout(function() {
console.log('wash');
callback();
}, 3000);
}
function dry(callback) {
setTimeout(function() {
console.log('dry');
callback();
}, 2000);
}
function fold(callback) {
setTimeout(function() {
console.log('fold');
callback();
}, 1000);
}
const doLaundry = (fns) => {
const firstCallback = () => console.log('done');
const firstFn = fns.reduceRight(
(nextCallback, fn) => () => fn(nextCallback),
firstCallback
);
firstFn();
}
doLaundry([wash, dry, fold]);
Or, for an easier to understand approach, promisify each callback and await them:
function wash(callback) {
setTimeout(function() {
console.log('wash');
callback();
}, 3000);
}
function dry(callback) {
setTimeout(function() {
console.log('dry');
callback();
}, 2000);
}
function fold(callback) {
setTimeout(function() {
console.log('fold');
callback();
}, 1000);
}
const toProm = fn => new Promise(resolve => fn(resolve));
const doLaundry = async (fns) => {
for (const fn of fns) {
await toProm(fn);
}
console.log('done');
}
doLaundry([wash, dry, fold]);

Try this simple code:
only one thing that you have to remember is, in the callback function if we are passed arguments, you have to write something in front of the callback like this
()=>
function wash(dry) {
console.log("wash");
setTimeout(dry, 3000);
}
function dry(fold) {
console.log("dry");
setTimeout(fold, 2000);
}
function fold(done) {
console.log("fold");
console.log("done");
}
setTimeout(() => wash(() => dry(() => fold("done"))), 4000);

function wash(callback){
setTimeout(()=>{
console.log('wash');
callback()
},3000)
}
function dry(callback){
setTimeout(()=>{
console.log('dry');
callback()
},2000)
}
function fold(callback){
setTimeout(()=>{
console.log('fold');
callback()
},1000)
}
function doLaundry(callback){
callback()
}
doLaundry(()=>{
wash(()=>{
dry(()=>{
fold(()=>{
console.log('done')
})
})
})
});

This one should do the job.
function doLaundry(actions) {
const [_wash, _dry, _fold] = actions
_wash(() => {
_dry(() => {
_fold(() => {
console.log('Done')
})
})
})
}
First line is destructuring the array, so it's elements are easier to access:
const [_wash, _dry, _fold] = actions
Function doLaundry takes array of callback functions as argument, which means when calling those functions inside of body of doLaundry, only names which it takes from arguments should be provided together with arguments that those callback functions are taking.
Since all of them take callbacks as arguments, arguments must be another function. First callback function's (in this case _wash) argument is another callback (_dry), therefore it takes another function as argument. If _wash's argument wasn't another function that takes callback as argument, it would be done like this:
_wash(_dry)
Last callback (_fold) also takes a callback as an argument which is in this case an anonymous function.

Related

Javascript - Get an object the owner of a property or function

I pass the callback to setTimeout and internally I need to determine who owns this callback. For example:
class Test1 {
func1() {
console.log('test1');
}
complete() {
console.log('complete');
}
}
function test2() {
console.log('test2');
}
function timeout(callback, delay) {
setTimeout(() => {
callback();
callback.getOwner()?.complete();
}, delay);
}
In this case, I need to return the owner of this callback in order to execute the complete () function.
let obj = new Test1();
timeout(obj.func1.bind(obj));
timeout(test2);
I understand that complete() can be done inside func1(), like this:
class Test1 {
func1() {
console.log('test1');
this.complete();
}
complete() {
console.log('complete');
}
}
But this is just a small example.

I can't control asynchronous tasks order using async-await function

I am facing an issue while using async-await function in javascript.Let's have a look my code first.
function take() {
setTimeout(() => {
console.log('take order');
}, 4000);
}
function complete() {
setTimeout(() => {
console.log('complete order');
}, 20);
}
async function processOrder() {
let a = await take();
let b = await complete();
}
processOrder();
In the code above,I used await to control the order of the tasks.But it didn'twork.The complete function exicuted before the taks function.But I used await to wait in the task function to exicute and then the complete function exicution.
This is not a real life issue.I wonder what is going on here.Can anyone please explain it to me?
your functions are not using promise that's why it doesn't work!
function take() {
return new Promise(resolve => {
setTimeout(() => {
console.log('take order');
resolve()
}, 4000);
})
}

Convert async await in while loop to promises

I can't figure out how to convert async await functionality in a while loop to a promise based implementation.
repl showing the async await version
https://repl.it/repls/IdealisticPepperyCoding
var dependency = false;
function checkDependency() {
return new Promise(resolve => {
setTimeout(() => {
dependency = true;
return resolve();
}, 1000)
});
}
async function isReady() {
while(!dependency) {
console.log('not loaded');
await checkDependency();
}
console.log('loaded')
}
isReady();
If I'm understanding you correctly, you're wanting to use Promises without async functions instead of Promises with async functions, and the sample checkDependency may actually not set dependency = true in all cases, so you want to "loop."
Equivalent functionality could look something like this, where you "recursively" call the check function. It won't actually be recursive and lead to a stack overflow, though, since the call is done in an async callback:
var dependency = false;
function checkDependency() {
return new Promise(resolve => {
setTimeout(() => {
dependency = true;
return resolve();
}, 1000)
});
}
function isReady() {
if (!dependency) {
return checkDependency().then(isReady);
}
return Promise.resolve(true);
}
isReady().then(() => {
console.log('loaded')
});
You don't need the while loop.
checkDependency().then(() => { console.log('loaded');});
You don't need to return recolve() just call it.
Call the function then within the function isReady
function checkDependency() {
return new Promise(resolve => {
setTimeout(resolve, 1000);
});
}
function isReady() {
console.log('not loaded');
checkDependency().then(() => {
console.log('loaded')
});
}
isReady();

Repeating call to function based on its callback

I have the following setup:
const foo = () => {
bar((err,payload) => {
// some stuff happens here
}
}
So I need to continuously call "bar" inside of "foo" until a certain outcome happens in the "some stuff happens here" part. But I obviously have to wait for the outcome of the callback before re-calling "bar" - how could I structure this?
Try using the new await and async in ES6.
const foo = async () => {
var myOutcome;
while (/*CHECK HERE*/) {
try {
myOutcome = await /* call async javascript function here */
} catch (e) {
// Handle error here
}
}
}
This all relies on Javascript Promises, so long as that function returns a promise it will automatically be run more of a synchronous like manner.
Edit if the function only supports callbacks you can wrap it in a promise like so.
function myCallbackFunctionPromise() {
return new Promise((resolve, reject) => {
callbackFunction((err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}

How to call javascript array of methods having callbacks to run sequentially?

I have the following methods to be called sequentially.
Note that timeout is differing so by default it will run based on timeout.
function asyncTask1(done) {
setTimeout(() => {
console.log('task 1 done');
done(1);
}, 500);
}
function asyncTask2(done) {
setTimeout(() => {
console.log('task 2 done');
done(2);
}, 400);
}
function asyncTask3(done) {
setTimeout(() => {
console.log('task 3 done');
done(3);
}, 300);
}
function sequential(tasks = []) {
}
sequential(tasks);
You can do it recursively:
function sequential([first, ...last], done) {
if (!first) done();
else first(() => sequential(last, done);
}
This was a very useful reply, but took me a bit of time to put it all together. Here is the function in use
function done() {
console.log("DONE")
}
var callbacks = [
function callback1(next) {
console.log("callback1")
next()
},
function callback2(next) {
console.log("callback2")
next()
},
function callback3(next) {
console.log("callback3")
next()
},
function callback4(next) {
console.log("callback4")
next()
},
function callback5(next) {
console.log("callback5")
next()
}
]
function sequential([first, ...last], done) {
if (!first)
done();
else
first(() => {sequential(last,done);})
}
//And call it.
sequential(callbacks, done);

Categories