When it comes to dealing with timing issue, it is tempting and easy to put a "quick"
browser.sleep(<timeout_in_milliseconds>) and move on.
The problem is, it would some day fail. There is no golden/generic rule on what sleep timeout to set and, hence, at some point due to network or performance or other issues, it might take more time for a page to load or element to become visible etc. Plus, most of the time, you would end up waiting more than you actually should.
browser.wait() on the other hand works differently. You provide an Expected Condition function for Protractor/WebDriverJS to execute and wait for the result of the function to evaluate to true. Protractor would continuously execute the function and stop once the result of the function evaluates to true or a configurable timeout has been reached.
There are multiple built-in Expected Conditions, but you can also create and use a custom one (sample here).