javascript - 等待数据返回,与 Angular 和 Breeze 同步调用

标签 javascript angularjs promise breeze

我正在开发一个小型博客引擎,用户可以在其中创建博客条目并可以将标签链接到条目。它是多对多关系,但由于 Breeze 还无法管理这种关系,我必须将联接表暴露给 Breeze ,以便我可以逐步保存数据。我的问题就在这里。

表格:

  • 博客条目
  • 博客条目标签
  • 标签

场景:

  • 用户打开“新博客条目”表单或选择要编辑的现有博客
  • 输入文本等
  • 选择一个或多个标签

业务逻辑:

  • 通过 Breeze 创建一个新实体/查询所选实体
  • 保存博客条目(第一个服务器调用,如果博客条目是新条目,则返回 blog_id)
  • 检查标签和博客条目之间已存在的连接,如果博客条目被编辑,则现有的 blogEntry-标签关系可能会发生变化(第二次服务器调用)
  • 根据标签名称从标签表中选择 tag_id(第三次服务器调用)
  • 通过 Breeze 创建 BlogEntrytag 实体
  • 将 BlogEntrytag 实体保存到数据库中(第四次服务器调用)

我认为顺序必须是连续的。

我有这段代码,正如您所看到的附加屏幕截图,由“_blogEntryEnttity”标记的控制台日志记录不会等到数据从服务器返回,并且它将在由“_blogEntryEnttity inside”标记的控制台日志记录之前执行。当代码稍后尝试设置 title 属性时,将引发引用异常。

var blogEntryEntityQueryPromise = datacontext.blogentry.getById(_blogsObject.id);

                    blogEntryEntityQueryPromise.then(function (result)
                    {
                        console.log('result', result);
                        _blogEntryEntity = result[0];
                        console.log('_blogEntryEnttity inside', _blogEntryEntity);
                        //if I need synchronous execution then I have to put the code here which must be executed consecutively
                    });
                    console.log('_blogEntryEnttity', _blogEntryEntity);
                }

                //mapping the values we got
                _blogEntryEntity.title = _blogsObject.title;
                _blogEntryEntity.leadWithMarkup = _blogsObject.leadWithMarkup;
                _blogEntryEntity.leadWithoutMarkup = _blogsObject.leadWithoutMarkup;
                _blogEntryEntity.bodyWithMarkup = _blogsObject.bodyWithMarkup;
                _blogEntryEntity.bodyWithoutMarkup = _blogsObject.bodyWithoutMarkup;
                console.log('_blogEntryEnttity', _blogEntryEntity);

示例来自here .

我的问题是,为什么不等到数据返回呢?遇到这样的情况,该如何处理呢?

但是,我发现,如果我需要同步执行,那么我应该将代码放入从 Promise 检索数据之后的 success 方法中。然而,我真的不喜欢这个解决方案,因为我的代码在一段时间后会变得很难看并且难以维护。

datacontext.blogentry.getById 如下所示,实现在抽象类中,您也可以找到下面的代码。整个存储库模式来自 John Papa 的 course在 Pluralsight 上。

存储库类方法

function getById(id)
        {

            return this._getById(this.entityName, id);
        }

抽象存储库类方法。根据Breeze's documentation page EntityQuery 类的执行方法返回一个 Promise。

function _getById(resource, id) {

            var self = this;
            var manager = self.newManager;
            var Predicate = breeze.Predicate;
            var p1 = new Predicate('id', '==', id);

            return EntityQuery.from(resource)
                .where(p1)
                .using(manager).execute()
                .then(success).catch(_queryFailed);

            function success(data) {
                return data.results;
            }
        }

Execution order

非常感谢您的帮助!

最佳答案

我认为您不需要所有这些往返。我会这样做:

  1. 查询所有可用的标签实体,以便它们位于 EntityManager 的缓存中(无论如何,您都需要它们来填充 UI)。

  2. 如果是现有的BlogEntry,则只需查询该BlogEntry及其所有关联的BlogEntryTag实体即可; Breeze 会将 BlogEntryTags 连接到缓存中与其关联的标签。如果用户选择/取消选择 BlogEntry 的标签,您将添加/删除 BlogEntryTags。

var query = EntityQuery.from("BlogEntries").where("id", "==", id).expand("BlogEntryTags");

  • 如果它是一个新的 BlogEntry,则它不会有任何 BlogEntryTags。在用户选择一些标签后,您将在保存时创建这些标签。

  • 通过一次 saveChanges 调用将添加/更新的 BlogEntry 和任何添加/删除的 BlogEntryTag 实体保存到数据库。

  • 请参阅Presenting Many-to-Many doc 及其 associated plunker进行更深入的研究。 UI 与您想要的不同,但底层概念很有用。

    关于javascript - 等待数据返回,与 Angular 和 Breeze 同步调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29808749/

    相关文章:

    javascript - 是否有关于将自定义操作绑定(bind)到什么的最佳实践?

    javascript - 在javascript中查找具有特定字符的单词并替换整个单词

    AngularJS:缩小破坏了我的指令

    javascript - Cordova 应用程序从头开始,关于 ngCordova、Ionic 和 Typescript 的决定

    scala - 适合使用 Futures 和 Promises 进行延迟初始化吗?

    javascript - 使用网络音频 API 播放多个声音时如何消除噪音?

    javascript - 无法让 JavaScript RegEx 工作

    ios - 选择选项在 IOS 中不适用于 ionic 1 应用程序

    javascript - 返回错误和抛出错误的区别

    javascript - 如何在 while 循环中串联连接 Promise