等到数据returns,用angular和breeze同步调用

Wait until the data returns, synchronous call with angular and breeze

我正在开发一个小型博客引擎,用户可以在其中创建博客条目,并且可以为条目添加 link 标签。它是 many-to-many 关系,但由于 Breeze 尚无法管理此关系,我必须将连接 table 公开到 breeze 以便我可以保留数据 step-by-step.而我的问题就在这里。

表格:

场景:

业务逻辑:

我觉得顺序一定是连续的

我有这段代码,正如您所看到的附加屏幕截图,由“_blogEntryEnttity”标记的控制台日志记录不会等到来自服务器的数据returns,它将在由标记的控制台日志记录之前执行'_blogEntryEnttity 里面'。几行后尝试设置标题 属性 时,代码将抛出引用异常。

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 如下所示,实现是抽象的 class,您也可以在下面找到代码。整个存储库模式来自 John Papa 在 Pluralsight 上的 course

存储库class 方法

function getById(id)
        {

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

抽象存储库class 方法。根据 Breeze's documentation page EntityQuery class' 执行方法 returns 一个 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;
            }
        }

在此先感谢您的帮助!

why it is not wait until the data comes back?

因为承诺不会神奇地同步执行。它们仍然是异步的,它们 still rely on callbacks.

What is the way of handling cases like this?

您需要将应该等待的代码放在 then 回调中。

However, I really don't like this solution because my code will be ugly after a while and hard to maintain.

不一定,你可以用promises写出简洁优雅的异步代码。如果你的代码变得太多了,那就把它的一部分抽象成自己的函数。您应该能够获得干净且 flat 承诺链。

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

  1. 查询所有可用的 Tag 实体,因此它们将在 EntityManager 的缓存中(无论如何您都需要这些来填充 UI)。

  2. 如果是现有的BlogEntry,只需查询BlogEntry及其所有关联的BlogEntryTag实体; Breeze 会将 BlogEntryTags 连接到它们在缓存中的关联标签。如果用户 selects/unselects BlogEntry 的标签,您将 add/delete BlogEntryTags。

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

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

  2. 在单个 saveChanges 调用中将 added/updated BlogEntry 和任何 added/deleted BlogEntryTag 实体保存到数据库。

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