简体   繁体   English

AngularJS - “链接承诺”与其他功能之间

[英]AngularJS - “Chaining promises” with other functions in between

So I have this problem. 所以我有这个问题。 I'm fairly new to angular and I've been told to modify a directive which manages forms to make the submit button disabled then enabled again when all the work is done. 我对角度很新,我被告知修改一个管理表单的指令,使提交按钮被禁用,然后在完成所有工作后再次启用。

Since the functions being called usually have async calls, simply adding code sequentially doesn't work. 由于被调用的函数通常具有异步调用,因此仅按顺序添加代码不起作用。

var ngSubmit = function() {
  vm.disabled = true;
  $scope.ngSubmitFunction();
  vm.disabled = false;
}

Button is enabled before async calls under ngSubmitFunction() finish. 在ngSubmitFunction()完​​成之前的异步调用之前启用按钮。

So I thought a promise would fix that and made something like: 所以我认为一个承诺会解决这个问题并做出类似的事情:

var promise = function() {
  return $q(function (resolve) {$scope.ngSubmitFunction()});
}
var ngSubmit = function() {
  vm.disabled = true;
  promise().then(function() {
   vm.disabled = false;
  });
}

This doesn't output any error but never enables the button again (.then is never called). 这不会输出任何错误,但永远不会再次启用该按钮(。然后永远不会调用)。

Tried different kind of promises declaration, all with the same result, except for this one: 尝试了不同类型的承诺声明,所有结果都相同,除了这一个:

$scope.submitPromise = function() {
  return $q.when($scope.ngSubmitFunction());
}

This does call .then function, but again, doesn't wait for any child async function to finish. 这会调用.then函数,但同样不会等待任何子异步函数完成。 '.then' is called instantly, like the sequential version. '.then'会立即调用,就像顺序版一样。

Have in mind that I don't know what's under ngSubmitFunction(). 请记住,我不知道ngSubmitFunction()下的内容。 It is used by dozens developers and it may contain from 0 to multiple async calls. 它由几十个开发人员使用,它可能包含从0到多个异步调用。 But typical scenario is something like: 但典型情况如下:

ngSubmitFunction() calls func() ngSubmitFunction()调用func()

-- func() decides wether to call create() or update() - func()决定是否调用create()或update()

-- -- update() calls a elementFactory.update() which is an async call - - update()调用一个异步调用的elementFactory.update()

-- -- -- elementFactory.update().then(function()) is called when finished. - - - elementFactory.update()。then(function())在完成时被调用。

-- -- -- -- At THIS point, I should enable the button again. - - - - 此时,我应该再次启用该按钮。

How can I achieve this? 我怎样才能做到这一点? is there a way to chain promises with non-promises functions in between? 有没有办法将承诺与非承诺函数联系在一起? or another way to make a code only execute when everything else is done? 或其他方式使代码只在其他一切完成时执行? I thought about creating an event at DataFactory when an async call is over but if the update() function was calling to more than one async call this wouldn't work. 我想在异步调用结束时在DataFactory上创建一个事件,但如果update()函数调用多个异步调用,这将无效。

If you are using promises, your async functions should return promises, if they do it should work like this: 如果你正在使用promises,你的异步函数应该返回promises,如果他们这样做,它应该像这样工作:

var ngSubmit = function() {
  vm.disabled = true;
  $scope.ngSubmitFunction().then(() => {
      vm.disabled = false;
  });
}

I don't know what's under ngSubmitFunction() 我不知道ngSubmitFunction()下的ngSubmitFunction()是什么

Then you're out of luck, promises won't help you here. 然后你运气不好,承诺不会帮助你。 Promises or $q.when cannot magically inspect the call and see what asynchronous things it started or even wait for them - ngSubmitFunction() needs to return a promise for its asynchronous results itself. Promises或$q.when无法神奇地检查调用并查看它启动的异步事件甚至等待它们 - ngSubmitFunction()需要为其异步结果本身返回一个promise。

You need to make every function in your codebase which (possibly) does something asynchronous that needs to be awaitable return a promise. 您需要在代码库中创建每个函数(可能)执行需要等待的异步返回promise。 There's no way around this. 没有办法解决这个问题。

Well, in case someone wonders, we haven't found a solution to that (there probably isn't). 好吧,如果有人想知道,我们还没有找到解决方案(可能没有)。 So we will go with the adding returns to all the chain of functions to make sure the ngSubmitFunction recieves a promise and therefor can wait for it to finish before calling '.then'. 因此,我们将对所有函数链添加返回以确保ngSubmitFunction收到一个promise,因此可以在调用'.then'之前等待它完成。 Not only this makes it work for the cases where there's only one promise implied but it is also a good programming practice. 这不仅使得它适用于只有一个承诺隐含的情况,但它也是一个很好的编程实践。

Cases with more than one promise are scarce so we will treat them individually on the controller itself. 具有多个承诺的案例很少,因此我们将在控制器本身上单独处理它们。

Thank you all for your comments. 谢谢大家的意见。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM