If these are personal projects, and your main aim is learning, then one possible solution is to just accept that you're not finishing them: once you start doodling around instead of doing actual work on the project, you have probably learned what you wanted to learn, and there is no shame in dropping the project. OTOH, finished projects are a nice thing to have in your showcase, so maybe aiming for showcase-able code is a good incentive.
If, however, you actually need the finished product, the key is YAGNI (You Ain't Gonna Need It (yet)): For every change you make, ask yourself if it is absolutely crucial for the project that you implement this particular change right now. If the answer is "no" or "maybe", don't implement it. In other words, get your priorities straight.
Another good rule-of-thumb is that you should have something shippable at any given moment. No matter what your change, if you get interrupted at any moment during development, you should be able to produce a working, shippable version instantly. To achieve this, you probably want to use a version control system (and be strict about committing individual changes individually, tagging every shippable version, branching for every non-trivial change, etc.), you want to divide your work into small bursts (something like 30 to 60 minutes each), and you want to be religious about fixing bugs before adding features - no matter how hard you want or need this feature, if something else is broken, fix it first.
You also want to minimize the effort required to pick up back where you left. Short development iterations help, as they reduce the risk of dropping your work halfway through a development session; good documentation is crucial (unfortunately, writing good documentation is an art form in itself); keeping a To-Do-list or using a bug tracker also helps, as it allows you to visualize what needs to be done, what the priorities are, and what you were working on the last time you stopped.
And finally, keep in mind that shipping is a feature: shipping a version that barely works, but is just good enough to do whatever it needs to do is often an acceptable alternative to spending a few more months to polish the application to perfection.