We help IT Professionals succeed at work.

Can This Code Work Using an Anonymous Function?

Bruce Gust
Bruce Gust asked
on
This works:

<script>

$(document).ready(function() {
	
	const fetchData = () => {
	  const promise = new Promise((resolve, reject) => {
		setTimeout(() => {
		  resolve("Loose Cannon Fitness");
		}, 100);
	  });
	  return promise;
	};
	
	
	setTimeout( async () => {
	  console.log("Smith and Gone");
	  var text = await fetchData();
	  console.log(text);
	}, 200);


});

</script>

Open in new window


What I'm attempting to do is get a better understanding of Callbacks, Promises and Async / Await(s).

To do that, I started with a very basic example and just built on that - adding / editing things in order to match what represented the new paradigm.

Here's the basic Callback:

$(document).ready(function() {
	
	x = function(cb) {
		setTimeout(function() {
			console.log("Smith and Gone");
			cb();
		}, 200);
	}

	y = function() {
		console.log("Loose Cannon Fitness");
	}
	
	x(y);
	
});

Open in new window


Here's the same result structured using ES6:

$(document).ready(function() {
	
	x = (cb) => {
		setTimeout(function() {
			console.log("Smith and Gone");
			cb();
		}, 200);
	}

	let y = () => {
		console.log("Loose Cannon Fitness");
	}
	
	x(y);
	
});

Open in new window


Here it is written using Promises:

const fetchData = () => {
  const promise = new Promise((resolve, reject) => {
	setTimeout(() => {
	  resolve("Loose Cannon Fitness");
	}, 100);
  });
  return promise;
};

setTimeout(() => {
  console.log("Smith and Gone");
  fetchData()
  .then(text => {
	console.log(text);
  });
}, 200);

Open in new window


And here it is written using an Async / Await dynamic:

$(document).ready(function() {
	
	const fetchData = () => {
	  const promise = new Promise((resolve, reject) => {
		setTimeout(() => {
		  resolve("Loose Cannon Fitness");
		}, 100);
	  });
	  return promise;
	};
	
	setTimeout( async () => {
	  console.log("Smith and Gone");
	  var text = await fetchData();
	  console.log(text);
	}, 200);

});

Open in new window


Just for the sake of drill, I did this:

$(document).ready(function() {
		
	const fetchData = () => {
		setTimeout(function() {
			console.log("Loose Cannon Fitness");
		}, 200);
	}

       setTimeout( async () => {
       console.log("Smith and Gone");
       var text = await fetchData();
       console.log(text);
      }, 200);
 
});

Open in new window


What I wanted to do was make "fetchData" a regular ES6 function as opposed to something that was incorporating a Promise.

The result was an error that looked like this:

Smith and Gone
stunt.php:54 undefined
stunt.php:25 Loose Cannon Fitness


Line #54 was "console.log(text)."

I'm assuming that "undefined" is a result of the fact that "await" is expecting a Promise.

Is that correct?

That said, is there a way to do what I've got written above where my "setTimeout" function works as it "awaits" fetchData written as an anonymous funtion?

This isn't something I would use in a practical setting. Rather, it's something I'm putting together for my own edification

What do you think?

In an effort to figure it out for myself, I tried this:

	const fetchData = () => {
		setTimeout(function() {
			//console.log("Loose Cannon Fitness");
			//var text = "Loose Cannon Fitness";
			//return text;
			return "Loose Cannon Fitness";
		}, 200);
	}

Open in new window


That didn't work.

I tried this:

	const fetchData = () => {
		var text="";
		setTimeout(function() {
			//console.log("Loose Cannon Fitness");
			var text = "Loose Cannon Fitness";
		}, 200);
		return text;
	}

Open in new window


I realize that I'm all over the map. But what I'm trying to nail down is the way in which "fetchData" would need to be constructed if I crafted it without a Promise. Is that even possible? Does "await" mandate a Promise in order for it to work?
Comment
Watch Question

Most Valuable Expert 2017
Distinguished Expert 2019
Commented:
I'm assuming that "undefined" is a result of the fact that "await" is expecting a Promise.
The problem here is that the anonymous function is not a promise - it does not resolve asynchronously and it does not return a promise so when you do the assignment on line 11 with the await you are going to get nothing back.

Let's say you did this
const fetchData = () => {
		setTimeout(function() {
			console.log("Loose Cannon Fitness");
		}, 200);
    return "Yippee"; // <====== NOTE THIS LINE ADDED
	}

Open in new window

You will no longer get undefined.
Why?
Because the anonymous function returned a value.
await does not wait for the timeout because it is not wrapped in a promise so it gets the value of whatever the anonymous function returns (which is not what is in the timeout - the function wrapper that creates the timeout is the key bit here - and yours by default does not return anything).
When we return a string - it is output - and then sometime later the timeout message happens but you will notice the order is not the same had the timeout been wrapped in a promise. Yippee is output immediately on return from the call to the anon function.

If you had wrapped the timeout in a promise then the await would have waited for the promise to resolve and then output the string from the timeout (Yippee goes away now because it is replaced by a Promise return).

Make sense?
Bruce GustPHP Developer

Author

Commented:
Julian!

This is perfect!

Thank you!

If you have a moment, I could use your expertise in solving a piece of Mongodb code I'm working on. The question is at https://www.experts-exchange.com/questions/29172496/Popping-the-Hood-on-this-Function-What-is-getPipelineColumns.html

Bring it!

You're from South Africa, aren't you? What's the South African equivalent to "Bring it?"