Code Execution in Promise and using return stateme

2019-03-02 15:46发布

问题:

This question already has an answer here:

  • Do I need to return after early resolve/reject? 6 answers

Here, while using promise should i need to return the resolve and reject methods

the code executes smoothly but if there are multiple conditions statements then will reject and resolve auto-ends or we have to use return statements

 const getJobs = (filters, fieldASTs) => new Promise((resolve, reject) => {
        const AST = fieldASTs.fieldNodes[0].selectionSet.selections[0]
            .selectionSet.selections[0].selectionSet.selections;
        const FIELDS = _.map(AST, n => n.name.value);

        if (_.includes(FIELDS, 'employer')) {
            Job.find(filters, (err, d) => {
                if (err) return reject(err);

             // should i need to return or just use reject

                if (err === null && d === null) return reject(null);
             // return resolve(d) or only resolve()
                return resolve(d);
            });
        } else {
            Job.find(filters, (err, d) => {
              // here also
                if (err) return reject(err);
                // here too
                return resolve(d);
            });
        }
    });

回答1:

Whether or not to use a return statement is entirely up the desired flow of control in your function. It actually has nothing to do with promises. If you don't want or need any more code in your function to execute and you aren't already completely isolated in a conditional, then use a return to exit the function. Same issue whether you are or aren't using promises.

Remember, all resolve() or reject() do is change the state of the promise (assuming it is in the pending state) and then, any .then() or .catch() handlers are scheduled for future execution after the current running Javascript returns control back to the system. They are just functions calls like other functions calls.

You do not have to use return statements after calling resolve() or reject().

So, whether or not a return statement is appropriate depends entirely upon your code. If you don't want to execute more code in that block, then return. If you don't want to waste time potentially calling resolve() or reject() elsewhere in the block (which will not actually do anything to the promise), then use a return. If your code is already within a conditional block and nothing else will execute that you don't want to execute, then there is no need for a return.

For example, in this part of your code:

if (_.includes(FIELDS, 'employer')) {
    Job.find(filters, (err, d) => {
        if (err) return reject(err);

        if (err === null && d === null) return reject(null);
        return resolve(d);
    });
 }

it is appropriate to use the return because there is no need to execute any more code in the current function. If you omitted the return there, your code would still function fine (in this particular case) because the extra code you would run would not actually do anything since calling reject() or resolve() after you've already rejected or resolved the promise does not change anything. But, I consider it a wasteful and a bit confusing practice to let code run that doesn't need to run. So, I would always use either a return or a conditional in this case.

Personally, I'd probably write this code like this:

if (_.includes(FIELDS, 'employer')) {
    Job.find(filters, (err, d) => {
        if (err) return reject(err);
        if (d === null) return reject(new Error("unexpected null result from Job.find()"));
        return resolve(d);
    });
}

Note: I removed the check for if (err === null) because that should be the success case.

Or, I would have promisified Job.find() more generically at a lower level so my logic flow would all be promises.