【问题标题】:Promise is not resolving even after calling resolve()即使在调用 resolve() 之后,Promise 也没有解决
【发布时间】:2020-05-31 09:57:59
【问题描述】:

我在这里的问题可能听起来很少重复。但是我在stackoverflow上没有找到任何可以解决我的问题的答案。

我正在从我的一个函数中返回一个承诺。从数据库中获取一些数据后,承诺将得到解决。如果 db 表中没有数据,将被拒绝。此外,在解决 promise 之前,我必须对获取的数据进行一些处理,这就是我使用回调的原因。

我的代码片段

return new Promise((resolve, reject) => {


            ResourceModel.getById(resource_ID).then((data) => {
                if (data.length > 0) {
                    console.log(data);
                    resolve(data);
                    console.log("Resolve Function Called");
                } else {
                    console.log("No data available");
                    reject(new Error("No data available"));
                }
            });
        });

ResourceModel.getById()

static getById(id) {
        const _transaction = cds.transaction();

        return _transaction.run(SELECT.from(Resource).where({ ID: id }));
    }

cds.transaction()是SAP提供的cds framework方法之一。

我期望它做的是在成功获取所有记录后它应该调用提供的回调,我在其中编写了我的处理逻辑并在处理完成后调用resolve()

我在回调中接收数据,能够打印Data available,并且接收到的数据对象甚至在控制台上结束Promise Resolved。但令人惊讶的是,承诺没有得到解决

我可以说“承诺没有得到解决”,因为这个返回的承诺将由框架收集在 Promise.all() 中(如官方文档中所述 - https://cap.cloud.sap/docs/node.js/api#service-before)并在解决后返回响应。但我没有得到任何回应(既没有成功也没有失败)。 Postman 永远处于 loading... 状态。

上面的例子与setTimeout() 例子一起工作得很好。

我哪里错了?

【问题讨论】:

  • 我建议您显示整个请求处理程序(包括Promise.all() 所在的位置),以便我们可以从头到尾查看整个请求代码。仅供参考,让getById() 在内部使用承诺然后向调用者公开回调接口真的很奇怪。只是回报承诺。 getById() 中也没有错误处理。如果 Promise 被拒绝,你什么也不做。
  • 我认为您对问题所在做出了一些错误的假设。我们需要查看更多此请求中涉及的代码。如果您在控制台中看到“可用数据”,但之前没有看到“无可用数据”,那么您的承诺将得到解决。因此,问题可能在于如何使用该承诺。我们需要查看该代码。
  • @jfriend00,最初我从getById() 方法返回承诺,但这也不起作用。从编码标准的角度来看,我完全同意你的看法,这是我需要做的。不幸的是,我无法显示Promise.all(),因为这是通过 sap 的 cap 框架实现的。框架正在处理所有这些问题。
  • 其实你可以把这个promise看作是中间件方法之一。框架将所有这些中间件方法收集在 Promise.all() 中,并在解决或拒绝任何承诺时返回 HTTP 响应。
  • 不幸的是,您在上面发布的代码中没有任何错误(除了回调一个承诺然后再次承诺回调的明显反模式)所以我们只能说您不需要更改任何使承诺解决的事情(正如你所说,它甚至打印“承诺解决”)。您在上面发布的代码没有任何问题。您未发布的代码可能有问题

标签: node.js promise callback sap-cap


【解决方案1】:

我在进行 API 调用或从数据库获取数据时遇到了此类错误。 通常,被调用资源或标头的类型不匹配的问题是返回类型错误。 在 getById() 中使用 console.log 并查看堆栈跟踪中发生了什么会很好。

【讨论】:

  • 嗨,Gopal,您能详细说明一下您的答案吗?你是怎么解决这个问题的?
  • 检查请求和响应标头,并尝试查看有时由于 API 管理不善导致响应出现错误部分
【解决方案2】:

首先,添加.catch() 以获得拒绝值。

function asyncOpr = () => { 
    return new Promise((resolve, reject) => {
        ResourceModel.getById(resource_ID).then((data) => {
                    if (data.length > 0) {
                        console.log(data);
                        resolve(data);
                        console.log("Resolve Function Called");
                    } else {
                        console.log("No data available");
                        reject(new Error("No data available"));
                    }
            }).catch(err => { /* handle error */ })
        });
  }

您可能无法获得解析值的原因是您使用此函数的方式。 正确的实现是:

function foo() {
  asyncOpr().then( val => console.log(val))
            .catch( err => console.log(err))
}

另外,请参阅使用async/await

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-12
    • 2020-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-22
    • 1970-01-01
    相关资源
    最近更新 更多