【问题标题】:Angular promise with a async/await failure带有 async/await 失败的 Angular 承诺
【发布时间】:2021-06-29 16:11:36
【问题描述】:

到目前为止,我所看到的解决我问题的建议似乎并不适用,或者我有一个很大的误解(我已经有一段时间没有接触过完整的堆栈了)。我有一项服务成功地访问了 Spring Boot 后端以获取进程列表:

function getReportProcesses(){
        var deferred =  $q.defer();
        var url = "fermentationReports/processes";
        httpService.get(url).then(function (data){
            deferred.resolve(data);
        }, function(msg){
            var errMsg  = "failed to get report processes: " +  msg;
            deferred.reject(errMsg);
        });
        return deferred.promise;
    }

我的目标是从下拉工厂中获取服务,将列表转换为 JSON,并将其传递给由下拉指令填充的下拉列表。当指令调用以下行来获取 JSON 时:

var data = ReportDdlFactory.getReportName();
            addAllTo(data, $scope.addAll);

在将data 作为undefined 添加到范围之前,它不会等待getReportName() 中的httpService 返回。这是工厂中的原始方法:

function getReportName() {

            try {
                FermentationReportsService.getReportProcesses().then(function (data) {
                    if (data.processes !== undefined) {

                        var output = {"data": []};
                        for (var i = 0; i < data.processes.length; i++) {
                            var currentLine = {"value": data.processes[i], "label": data.processes[i]};
                            output.data.push(currentLine);
                        }
                        return output;

                    } else {
                        return {
                            "data": [
                                {"value": "ERROR OBTAINING PROCESSES", "label": "ERROR OBTAINING PROCESSES"}]
                        };
                    }
                });
            } catch (err) {
                console.log("error caught: " + err);
            }
        }

我尝试将其更改为使用 async/await,因为 getReportProcesses() 已经返回了一个承诺:

async getReportName() {

            try {
                await FermentationReportsService.getReportProcesses().then(function (data) {
                    if (data.processes !== undefined) {

                        var output = {"data": []};
                        for (var i = 0; i < data.processes.length; i++) {
                            var currentLine = {"value": data.processes[i], "label": data.processes[i]};
                            output.data.push(currentLine);
                        }
                        return output;

                    } else {
                        return {
                            "data": [
                                {"value": "ERROR OBTAINING PROCESSES", "label": "ERROR OBTAINING PROCESSES"}]
                        };
                    }
                });
            } catch (err) {
                console.log("error caught: " + err);
            }
        }

但我总是从 jshint 得到这个:

 14 |            async getReportName() {
                 ^ Expected an assignment or function call and instead saw an expression.
 14 |            async getReportName() {
                      ^ Missing semicolon.
 14 |            async getReportName() {
                                      ^ Missing semicolon.
 17 |                    await FermentationReportsService.getReportProcesses().then(function (data) {
                         ^ Expected an assignment or function call and instead saw an expression.
 17 |                    await FermentationReportsService.getReportProcesses().then(function (data) {
                              ^ Missing semicolon.
  8 |                getReportName: getReportName,
                                    ^ 'getReportName' is not defined.
 14 |            async getReportName() {
                       ^ 'getReportName' is not defined.
 14 |            async getReportName() {
                 ^ 'async' is not defined.

我觉得我可能比需要的更难,或者我错过了一些简单的东西?


编辑:

经过更多研究,我确定应用程序以 'strict' 运行,强制 ECMA 5。有没有一种方法可以在不使用 ES6 方法的情况下强制响应?

【问题讨论】:

  • 在创建async 时,您仍然需要function 关键字。话虽如此,您在这两种情况下的问题只是您没有返回任何值。你需要return FermentationReportsService.getR...。然后,Promise 将解析为该值
  • 这段代码对我来说不清楚,所以如果可能的话,可以分享一个完整的版本超过stackblitz.com????????
  • @blex 谢谢,我会测试一下。
  • @malbarmavi 对不起,我不能。大多数代码是我工作的公司所拥有的专有和机密代码。我什至不得不混淆函数名称等才能安全地在这里发布我的问题。
  • @blex 当你对return FermentationReportsService.getR... 说时,我做不到。它以列表的形式出现,因此我需要遍历它们并返回我创建的 JSON 对象,该对象发生在 for 循环之后。返回output 变量是否会使进程无效?

标签: javascript angular angular-promise ecmascript-5 strict


【解决方案1】:

我可能会这样做:

function getReportName() {
  return FermentationReportsService
    .getReportProcesses()
    .then(function(data) {
      if (data.processes === undefined) {
        return { data: [
          { value: "ERROR OBTAINING PROCESSES", label: "ERROR OBTAINING PROCESSES" }
        ]};
      }
      
      return {
        data: data.processes.map(function(process) {
                return { value: process.value, label: process.value };
              })
      };
    })
    .catch(function(err) {
      console.log("error caught: " + err);
    });
}

【讨论】:

  • 感谢 blex。我做了一些更多的挖掘并确定这是使用 ES5 以“严格”方式运行的,因此这些方法显然在我的位置上是不允许的。你知道只使用 ES5 关键字的方法吗?显然,箭头、await、async 等是不允许的,jshint 也不会将它们识别为合法关键字。
  • @DarrelHolt 我已经编辑了答案,这应该可以工作
  • 应用程序正确构建并传递了 jshint,但它仍然会在执行 getReportName() 之前将 data 添加到范围内的指令行。 data 对象也有这个结构:{ "$$state": { "status": 0 } }。我是否应该在指令 async 中对 getReportName() 进行调用方法,以便它也等待?
  • 哦,是的,我忘记了这部分。这个函数返回一个 Promise,所以它是异步的。您需要按照以下方式做一些事情:ReportDdlFactory.getReportName().then(function(data) { addAllTo(data, $scope.addAll); });
  • 谢谢,你明白了。还有一些调用的方法在指令中使用了data 变量,所以我把它们放在then 方法中,它工作得很好。
【解决方案2】:

通过使用 async/await,您不再需要使用 then

async function getReportName() {
  try {
    const data = await FermentationReportsService.getReportProcesses();
    if (data.processes !== undefined) {
      var output = { data: [] };
      for (var i = 0; i < data.processes.length; i++) {
        var currentLine = {
          value: data.processes[i],
          label: data.processes[i],
        };
        output.data.push(currentLine);
      }
      return output;
    } else {
      return {
        data: [
          {
            value: 'ERROR OBTAINING PROCESSES',
            label: 'ERROR OBTAINING PROCESSES',
          },
        ],
      };
    }
  } catch (err) {
    console.log('error caught: ' + err);
  }
}

查看这篇文章了解更多信息?javascript.info async/await

【讨论】:

  • 谢谢,我看到我的 jshint 仍在抱怨。首先,它在函数头中说明了异步:Expected an assignment or function call and instead saw an expression。后面跟async 没有定义。以及'const' is available in ES6。 async 是否需要定义或包含在模块工厂标头中?它还需要在await 之后的分号const data = await FermentationReportsService.getReportProcesses();
  • getReportName 是类的一部分吗?如果是这样,您需要 删除 function 关键字,但我不确定,因为如果您使用 angular ??,您不会共享组件的完整源代码
  • 感谢你们迄今为止的帮助。我做了一些更多的挖掘并确定这是使用 ES5 以“严格”方式运行的,因此这些方法显然在我的位置上是不允许的。你知道使用 ES5 的方法吗?显然,不允许使用箭头、等待、异步等,并且 jshint 不会将它们识别为合法关键字。
猜你喜欢
  • 2018-03-09
  • 1970-01-01
  • 2021-11-27
  • 2016-05-20
相关资源
最近更新 更多