I usually try to explain how promises work with an analogy using the DC hero The Flash. The Flash is a super hero who has super speed. This is a long explanation but I think its a fun and interesting way to get an idea of how asynchronous code works without really getting into any syntax.
JavaScript is like The Flash, in that its super crazy fast, but can only be in once place at a time (JavaScript is single threaded). This is important to keep in mind while reading through my analogy.
So imagine a scenario where you get to use The Flash for a day to help you do stuff. The Flash is super fast so he can complete a lot of tasks quickly. However, as I mentioned there is a limit, he can’t be in multiple places at one time, so he’s fast, but he needs to “jump” around while things are happening. To stay efficient, he makes use of promising to come back when its his turn to perform the task rather than waiting the whole time.
So lets imagine you tasked The Flash with the mundane chore of doing your laundry. He’s super fast and gets all your clothes into into the washing machine at the nearby laundromat nearly instantly. However, it will take a while for your clothes to be done. During this time The Flash is just waiting for your laundry to finish and bring back to you. Being the awesome super hero he is, he promises to return to get the laundry when the laundrymat manager calls him back when your laundry is done, and he runs back to you so he can do whatever tasks you have for him next.
Now imagine you also want The Flash to get you a sandwich at a nearby deli. There’s now a problem with this, as The Flash can’t be in two places at one time. Even though he is crazy fast he has already promised to get back and get your laundry when its done, and now he also has to run over to the deli to get your sandwich. Again he has to wait in line for his turn make the order, and then wait for the sandwich to be made. While these task are being handled, he promises the manager of the deli to call him back when its his turn to make your order, and he runs back to you so you can tell him to do other tasks.
Now imagine you can’t think of any tasks for The Flash in the few seconds it took him to start these 2 task, which are now pending as he has to wait for the laundromat to call back, and the person in line to call and tell him its his turn to make the order.
He stands there for a few minutes not doing anything as all these other tasks are asynchronous. He suddenly gets a call back that its his turn to make his order for your sandwhich and dashes off. He makes the order as you like it, and the people at the deli start making it. He then promises to come back when the manager of the deli tells him, by calling him back when the sandwhich is done.
So he runs back to you and waits again for any possible tasks you have. Again you can’t think of any. After some more time the deli people call him back, and he runs back to get the sandwich and brings it back to you so you can stuff your face ;D
While your being happy and eating, The Flash gets another call from the laundromat that your laundry is done, and he dashes over and returns them to you.
You thank The Flash for his help and tell him to take the rest of the day off. 
So to review The Flash does a few interesting things here.
He doesn’t wait for things to finish, IE he doesn’t wait in line for his turn, or wait for your laundry to be done, he only promises to come back when they call him back when the task is finished. This way he can continue to be available to you during these times, and can essentially perform multiple tasks at once.
JavaScript is the same, in that it can perform multiple slow tasks at once by relying on callbacks and promising to come back later when the callback is executed. So if your making a network call, which can take several seconds you can use a promise-callback to have JS come back when the data is available.
The other thing about The Flash, is that because he is so fast, he generally isn’t really “waiting” to do anything except receive more commands.
This is also true for JavaScript, which will continue to execute commands when they are made, but generally will complete them and be waiting for these asynchronous and slow tasks to be completed by other people/systems and call him back when they are done.
In both scenarios The Flash/JavaScript ends up “jumping around” to what requires his attention, and a key part of that is using promise-callbacks to let him know.
Finally its worth mentioning that an alternate approach is to just have a superhero who duplicates themselves and performs each task at normal speed, but is in multiple places at once. This is called multi-threaded programming, which other languages can use to perform multiple tasks, but JavaScript doesn’t really utilize this structure or approach, but its worth keeping in mind.