有条件地在另一个承诺中呼唤承诺

时间:2016-09-21 13:46:42

标签: javascript promise q

这基本上是我的代码,使用q

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

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

但是,我现在需要根据某个条件执行一个步骤。此步骤调用另一个也返回promise的对象。所以我有嵌套的承诺,如果这是正确的术语。

这样的事情:

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;

但是这不起作用(name属性仍然是'peter')。可能是因为我的内心承诺在以后得到解决?

我也尝试了这个,但如果我调用返回promise的otherService,它就不起作用了。如果我只设置值,它确实有效:

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;
    });

这里的名字是'john',而不是'mary'。

显然我误解了承诺,但我无法理解它。

2 个答案:

答案 0 :(得分:2)

不推荐使用延迟。如果有的话,你应该使用Q.Promise构造函数,但你甚至不需要它。只需使用Q function创建一个符合您价值的承诺。

现在您可以(并且应该)将代码简化为

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

答案 1 :(得分:1)

使用Promises控制流程是...... 有趣

无论如何,你几乎就在那里,你可以在Promise中嵌入Promise并将它们链接起来。但是,如果要嵌入它们,则必须return嵌入式Promise链:

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可以获取值或其他Promise,它将处理流量。因此,当我们在returnthen时,我们返回的值可能是另一个Promise或只是一个值。机器将负责为我们打开包装。