0

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?

3
  • Must the functions be asynchronous? Commented Mar 10, 2021 at 2:16
  • No mention of asynch in the exercise description. Commented Mar 10, 2021 at 2:18
  • callback functions are not defined... Commented Mar 10, 2021 at 2:30

4 Answers 4

1

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]);

Sign up to request clarification or add additional context in comments.

2 Comments

I'm not supposed to tamper with the function definitions, how would implementation with callbacks taken into consideration look like? Thanks btw!
Thought you said the functions don't need to be asynchronous? But there are other ways, one sec...
0

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);    

Comments

0
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')
       })
   })
})
});

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
0

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.

2 Comments

Please add some explanation for your solution.
Of course, callback hells are a bit complicated. I edited post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.