【问题标题】:Calling promise in another promise, conditionally有条件地在另一个 promise 中调用 promise
【发布时间】:2016-09-22 00:20:37
【问题描述】:

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

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

d.resolve(result);
return d.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')。可能是因为我内心的承诺在稍后的时刻得到解决?

我也试过这个,但是如果我调用 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”。

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

【问题讨论】:

标签: javascript promise q


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    使用 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,它将处理流程。因此,当我们在then 中使用return 时,我们返回的值可以是另一个Promise 或只是一个值。机器会帮我们打开包装。

    【讨论】:

    • 您的代码正在运行,但过于复杂,我不得不认为它没有用。
    • @Bergi 很抱歉你有这种感觉。我只是复制了 OP,以免进一步混淆作者。是的,代码可能更具表现力。由于该帖子是关于 Promise 控制流的,因此有必要展示一个完整的示例。在我看来,作者对嵌入式承诺等感到困惑。
    • 这很复杂,但同时我已经对其进行了重构。此外,与我们在实际代码中的示例相比,我这里的示例微不足道。但是这个答案向我解释了我做错了什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 2019-04-07
    • 1970-01-01
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多