A promise is a function that does not execute immediately. Instead, you are 'promising' to respond to the status of a deferred object whenever it has completed it's processing. Essentially, you are creating an execution chain that simulates multiple threads. As soon as a deferred object is complete, it returns a status code, the calling function is able to respond to the status code, and return it's own status code if necessary, etc.
var deferred = $q.defer();
Here you are creating a deferred object, to hold the callbacks which will be executed later.
var promise = auth.$changePassword(email, oldPassword, newPassword);
This is the actual function, but you are not calling it here. You are making a variable to reference it, so that you can monitor it.
var rValue = promise.then(function(){
The .then() is the function that will be executed if the promise is successful. Here you are inlining a function that will execute upon the success of the promise's work.
}, function(error){
And then chaining the error function, which is to be executed if the promise fails. You are not actually doing anything here other than returning the error code, but you could do something to respond to the failure yourself.
deferred.resolve(promise);
This is the point where you are actually telling your deferred object to execute the code, wait for a result, then execute either the success or the failure code as appropriate. The promise is added to the execution chain, but your code is now free to continue without waiting and hanging up. As soon as the promise is finished and a success or failure is processed, one of your callback functions will process.
console.log(rValue);
Your function is not returning the actual values here because you don't want your function to stop and wait for a response before continuing, since this would block the program until the function completes.
return rValue;
You are returning your promise to the caller. Your function is a promise which is calling a promise which might be calling another promise, etc. if your function was not a promise, then even though the code you are calling is not blocking, your code would become a block as you wait for the execution to complete. By chaining promises together, you are able to define how you should respond without responding at exactly that moment. You are not returning the result directly, but instead 'promising' to return a success or fail, in this case passing through the success or fail from the function you are calling.