这个promise嵌套可以改为链接吗
Can this promise nesting be changed to chaining?
这是伪场景
| then (items) | then (items, actions)
getItems() | getActions(for:items) | apply(actions -> items)
:promise | :promise | model <= items
| | :synchronous
所以用文字来说:
- 我需要一份全局项目列表
- 很好。已提取项目
- 请求用户对以前提取的项目执行的操作
- 很好。已提取操作
- 将操作应用于项目列表
- 将项目放在模型上并在视图中显示
这是我使用的代码
return itemsResource
.getItems(userId)
.$promise
.then(function(items) {
return actionsResource
.getActions(items.map(i => i.id)) // pseudo mapper code here
.$promise
.then(function(actions) { // THIS IS NESTED so it sees both promise results
return [items, actions];
});
})
.then(helper.spread(function(items, actions) {
applyActions(items, actions);
$scope.model.items = items;
return items;
}));
正如您所理解的,我最初不能使用$q.all
,因为第二个(操作)承诺取决于第一个(项目)的结果。
为什么不返回带有项目的操作因为我为所有用户缓存项目,所以项目获取非常快。这与Stackoverflow的工作原理类似。不管用户提出什么要求,它们都只返回问题。然后,他们还会请求首选和忽略的标签,并应用于提取的问题。这可以很好地扩展,否则SO将需要更多的服务器来处理所有用户的初始问题列表,因为每个用户的请求都会产生不同的结果,所以缓存没有多大意义。
为什么不在提取项目后立即将其应用于$scope
这将消除额外的嵌套then
,这是真的。但我不会这么做,因为之后还有几个步骤,每次解决其中一个promise时,至少会执行一个$digest
循环。对于许多项目(相当复杂的对象),这可能会导致相当多的处理。这就是我坚持把项目传递到视图的最后一刻的原因。
问题
除了这两个解决方案之外,有没有办法避免嵌套的then
:
- 尽快将项目应用于
$scope
- 将项目保存到本地变量,然后使用它
如果可能的话,我想在不引入额外资源的情况下尽可能扁平化我的代码?
除非我遗漏了什么,否则这应该很简单,不是吗?
(为了清晰起见,我简化了您的一些内部功能签名)
itemsResource.getItems(userId)
.then(function(items) {
return $q.all({
items: items,
actions: actionResource.getActions(items)
});
})
.then(function(data) {
applyActions(data.items, data.actions);
$scope.model.items = data.items;
return data.items;
});
用于说明的plunker
将items->操作链的结果包装在promise中如何?类似的东西
return $q(function(resolve, reject) {
var outerItems;
itemsResource.getItems(userId).$promise
.then(getActions)
.then(function (actions) {
resolve([outerItems, actions]);
})
.catch(function (err) { reject(err); });
function getActions(items) {
outerItems = items;
return actionsResource.getActions(items).$promise
}
}).then(function (itemAndActions) {
var items = itemsAndActions[0],
actions = itemsAndActions[1];
return helper.spread(function (items, actions) {
applyActions(items, actions);
$scope.model.items = items;
return items;
})
});
相关文章:
- 创建一个类似链接的按钮,并通过Javascript函数打开一个新的弹出窗口
- 如何使用jQuery自动打开页面上的所有链接
- 动态地改变“”的URL;添加新项目”;链接使用javascript/jquery
- jquery动画可以通过编程链接吗
- 在单击href链接的同时下载文件
- 尽管链接成功并已成功下载,但未找到NPM模块
- 制作一个不带HTML a标记但在动画播放完毕后指向其他页面的超链接
- ReactJS映射:如何仅在url变量不为空时呈现html链接
- 单击页面上的链接后高度发生变化
- 将纯文本URL转换为可单击链接
- 这个promise嵌套可以改为链接吗
- JavaScript中可链接的、基于Promise的类接口
- 返回promise的链接函数;刷新超时后无法解析
- 不能链接在云代码中返回Promise的自定义函数
- JavaScript:多个promise对象被链接
- 链接2个异步调用(promise API)以串行运行
- 不知道如何将嵌套的promise与Q链接起来
- 使用promise链接同步与异步功能时的工作流
- 使用promise链接web服务调用并不总是有效的
- 链接promise时出现WebSQL错误“SQL执行被禁止”