AngularJS - 与其他功能之间的“链式承诺”
Posted
技术标签:
【中文标题】AngularJS - 与其他功能之间的“链式承诺”【英文标题】:AngularJS - "Chaining promises" with other functions in between 【发布时间】:2017-01-23 08:01:32 【问题描述】:所以我有这个问题。我对 Angular 还很陌生,有人告诉我修改一个管理表单的指令,以禁用提交按钮,然后在所有工作完成后再次启用。
由于被调用的函数通常有异步调用,简单地按顺序添加代码是行不通的。
var ngSubmit = function()
vm.disabled = true;
$scope.ngSubmitFunction();
vm.disabled = false;
在 ngSubmitFunction() 下的异步调用完成之前启用按钮。
所以我认为一个承诺会解决这个问题,并做了类似的事情:
var promise = function()
return $q(function (resolve) $scope.ngSubmitFunction());
var ngSubmit = function()
vm.disabled = true;
promise().then(function()
vm.disabled = false;
);
这不会输出任何错误,但永远不会再次启用按钮(.then 永远不会被调用)。
尝试了不同类型的 promise 声明,结果都一样,除了这个:
$scope.submitPromise = function()
return $q.when($scope.ngSubmitFunction());
这确实调用了 .then 函数,但同样,它不会等待任何子异步函数完成。 '.then' 被立即调用,就像顺序版本一样。
请记住,我不知道 ngSubmitFunction() 下的内容。它被许多开发人员使用,它可能包含从 0 到多个异步调用。但典型的情况是这样的:
ngSubmitFunction() 调用 func()
-- func() 决定是调用 create() 还是 update()
-- update() 调用 elementFactory.update() 这是一个异步调用
-- -- elementFactory.update().then(function()) 在完成时被调用。
-- -- -- -- 此时,我应该再次启用该按钮。
我怎样才能做到这一点?有没有办法将承诺与非承诺功能链接起来?或另一种方法使代码仅在其他所有操作完成后才执行?我想过在异步调用结束时在 DataFactory 创建一个事件,但如果 update() 函数调用了多个异步调用,这将不起作用。
【问题讨论】:
首先,ngSubmitFunction 返回什么?...如果它是异步函数并且不返回承诺,或者使用回调模式(您提供回调函数作为输入) ......然后你几乎不走运。 --- 你即将在 ngSubmit 中犯同样的错误,在你的 promise() 前添加一个 return。然后... 你的评论让我思考。所有的子函数都没有返回值,添加一个返回值使一切正常,因为最终总是有承诺。这样做的问题是它强制更改 3.5M 代码行项目的每个控制器,并且相信开发人员将始终对他们创建的每个函数都有一个 return 语句......不是机会。是否有另一种方法可以通过观察者或其他方式“检测”在 ngSubmitFunction() 的“引擎盖”下调用的承诺? 简短回答:不,没有,我当然会建议对调用堆栈下的承诺执行此行为。这只是一个很好的做法和常识IMO。 (显然有极端情况,但让我们离开吧)。即使所有的 Promise 都属于同一个框架,并且你破解了一些可以告诉你当前处于活动状态的 Promise 的东西,也不可能知道要等待哪个,你可能会说等待所有,但你可以保证看到无限锁在这里和那里等等。 【参考方案1】:如果你使用 Promise,你的 async 函数应该返回 Promise,如果他们这样做,它应该像这样工作:
var ngSubmit = function()
vm.disabled = true;
$scope.ngSubmitFunction().then(() =>
vm.disabled = false;
);
【讨论】:
【参考方案2】:我不知道
ngSubmitFunction()
下面是什么
那么你就不走运了,promise 在这里帮不了你。 Promise 或 $q.when
无法神奇地检查调用并查看它启动了哪些异步操作,甚至无法等待它们 - ngSubmitFunction()
需要为其异步结果本身返回一个 Promise。
您需要在您的代码库中创建 every 函数,该函数(可能)执行需要等待的异步操作返回一个承诺。没有办法解决这个问题。
【讨论】:
【参考方案3】:好吧,如果有人想知道,我们还没有找到解决方案(可能没有)。因此,我们将向所有函数链添加返回,以确保 ngSubmitFunction 收到一个 Promise,因此可以在调用 '.then' 之前等待它完成。这不仅使其适用于仅隐含一个承诺的情况,而且还是一种良好的编程习惯。
具有多个承诺的案例很少,因此我们将在控制器本身上单独处理它们。
谢谢大家的cmets。
【讨论】:
以上是关于AngularJS - 与其他功能之间的“链式承诺”的主要内容,如果未能解决你的问题,请参考以下文章