Calling promise in another promise, conditionally

穿精又带淫゛_ 提交于 2019-12-11 05:13:55

问题


This is basically my code, using q:

let d = Q.defer();
let result = {
    name: 'peter'
};

d.resolve(result);
return d.promise;

However, I now need to perform a step based on a certain condition. This step is calling another object that also returns a promise. So I'm having nested promises, if that's the correct term.

Something like this:

let d = Q.defer();
let result = {
    name: 'peter'
};

if (someParameter) {
    otherService.getValue() // Let's say it returns 'mary'
        .then((res) => {
            result.name = res;
        });
}

d.resolve(result);
return d.promise;

This doesn't work however (the name property is still 'peter'). Probably due to the fact that my inner promise is resolved at a later moment?

I've also tried this, but it doesn't work if I call the otherService which returns a promise. It does work if I just set the value:

let d = Q.defer();
let result = {
    name: 'peter'
};

d.resolve(result);
return d.promise
    .then((data) => {
        if (someParameter) {
            // Works
            data.name = 'john';

            // Doesn't work
            otherService.getValue()
                .then((res) => {
                    data.name = res;
                });
        }

        return data;
    });

Here the name will be 'john', not 'mary'.

Clearly I'm misunderstanding promises, but I can't wrap my head around it.


回答1:


Control flow with Promises is...fun?

Anyway, you are nearly there, you can embed a Promise in a Promise as well as chain them. However, if you are embedding them, you must return the embedded Promise chain:

let d = Q.defer();
let result = {
    name: 'peter'
};

d.resolve(result);
return d.promise
    .then((data) => {
        if (someParameter) {

            // Should work now that we return the Promise
            return otherService.getValue()
                .then((res) => {
                    data.name = res;
                    // And we have to return the data here as well
                    return data;
                });
        }

        return data;
    });

Promise resolve can take a value or another Promise and it will handle the flow. So, when we return inside a then, the value we are returning can be another Promise or just a value. The machinery will take care of unwrapping for us.




回答2:


Using deferreds is deprecated. If at all, you should use the Q.Promise constructor, but you don't even need that. Just use the Q function to create a promise that is fulfilled with your value.

Now you can (and should) simplify your code to

let d = someParameter ? otherService.getValue() : Q('peter');
return d.then(res => ({
    name: res
}));


来源:https://stackoverflow.com/questions/39618426/calling-promise-in-another-promise-conditionally

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!