【发布时间】:2015-09-15 03:50:44
【问题描述】:
我调用 getBubblesUserAccess 返回以特殊方式排序的 json 对象。结果我想运行一个 foreach 并获取其他消息,但我想按“顺序”返回它们。我知道它将运行这些异步,但必须有一种方法可以强制它“顺序”执行。 (以上代码是我最后一次尝试添加延迟...)
示例 伪代码 - 获取我的群组
{
"id":"016cd1fc-89a3-4e4a-9e6e-a102df1b03d9",
"parent":"53750396-7d26-41f3-913d-1b93276b9e09",
"name":"XX",
"createdBy":"c9c63080-2c5b-4e8e-a093-2cfcd628a9d0",
"hasWriteAccess":true,
"hasCreateAccess":false,
"hasDeleteAccess":false,
"hasAdminAccess":false,
"settingsBubbleId":"00000000-0000-0000-0000-000000000000"
},
{
"id":"016cd1fc-89a3-4e4a-9e6e-a102df1b03d9",
"parent":"53750396-7d26-41f3-913d-1b93276b9e09",
"name":"XX",
"createdBy":"c9c63080-2c5b-4e8e-a093-2cfcd628a9d0",
"hasWriteAccess":true,
"hasCreateAccess":false,
"hasDeleteAccess":false,
"hasAdminAccess":false,
"settingsBubbleId":"00000000-0000-0000-0000-000000000000"
}
从这个结果中,我想遍历那些父 id 字符串并调用另一个与之响应的服务。
伪代码 对于上面的每个组,调用另一个具有父 ID 的服务并获得结果。这个结果将被添加到一个新的 JSON 对象中。
"messages":[
{
"id":"f1d1aeda-d4e2-4563-85d5-d954c335b31c",
"text":"asd",
"sent":"2015-09-10T22:31:09.897+00:00",
"sender":"6b9e404b-ef37-4d07-9267-3e7b2579003b",
"senderName":"XXX XXXX"
},
{
"id":"a7ac0432-e945-440e-91ce-185170cbf3de",
"text":"asd",
"sent":"2015-09-10T22:28:24.383+00:00",
"sender":"c9c63080-2c5b-4e8e-a093-2cfcd628a9d0",
"senderName":"ZZZZZ ZZZZ"
},
我的问题是我的第二个 foreach 正在异步运行(应该如此),我希望它以与第一个 json 对象相同的顺序解析...
我的代码::
var loadBubblesAccess = function () {
if (vm.running && angular.isDefined(vm.running)) { return; }
vm.running = true;
vm.bubblesWithMessages = null;
return BubbleFactory.getBubblesUserAccess().then(function (bubblesAccessTo) {
return bubblesAccessTo;
});
},
loadSubBubbles = function (bubblesAccessTo) {
/**
* Result from chain method with all bubbles user has access to.
*/
var promiseArray = [];
//var promiseArrayError = [];
var i = 0;
/**
* Creates a defer object so that we will not resolve before for each loop has been gone thru.. async problems.
*/
var deferred = $q.defer();
angular.forEach(bubblesAccessTo, function (bubble) {
$log.error(JSON.stringify(bubblesAccessTo));
/**
* Get 20 because default thats default and cache and e-tags are done to that number..
*/
BubbleFactory.getBubbleMessages(bubble.id, 0, 20, false).then(function (data) {
i++;
if (data.messages.length > 0) {
promiseArray.push({ bubbleSortOrder: i, bubbleId: bubble.parent, bubbleName: bubble.name, bubbleMessagesId: bubble.id, bubbleMessages: smartTrim(data.messages[0].text, 400, ' ', ' ...'), bubbleMessagesSent: data.messages[0].sent });
}
else {
// console.log("YYYY::: " + bubble.parent);
promiseArray.push({ bubbleSortOrder:i, bubbleId: bubble.parent, bubbleName: bubble.name, bubbleMessagesId: bubble.id, bubbleMessages: 'Inget meddelande än..', bubbleMessagesSent: '' });
}
});
/**
* Check if we have gone thru all bubbles - when finished we resolve defer object.
*/
if(i===bubblesAccessTo.length)
{
deferred.resolve(promiseArray);
}
});
//$log.debug.log(promiseArray);
vm.bubblesWithMessages = promiseArray;
promiseArray.length = 0;
vm.running = false;
};
loadBubblesAccess().then(loadSubBubbles);
【问题讨论】:
-
如果你做了一个promise数组然后使用
$q.all(),结果应该在.then()的.then()中的正确顺序$q.all -
我尝试使用循环 foreach 并将它们添加到 promiseArray 的方法,然后在 q$.all 中执行它们,但结果相同。 :( 你确定它会用 q.all 以正确的顺序执行它们吗?
-
单个回调总是会出现问题,你必须从 .all() 的单个回调中获取数据
-
您可以使用
[].reduce按顺序浏览它们,等待一个完成后再调用下一个。查看本文中的“Collection Kerfuffle”部分:taoofcode.net/promise-anti-patterns -
我认为我应该使用 .spread - 我调用每个函数并返回结果,然后我会将结果合并到一个 json 数组中,然后发送到控制器。因为其中一件事是使用 $q.all 我得到了结果,但我也想从第一个结果中获得信息。我回家后会尝试这种方法。
q.all([loadSomething(), loadAnotherThing()]) .spread(function(something, another) { DoSomethingOnThem(something, another); });