简体   繁体   English

保持回调函数执行,直到诺言完成

[英]Hold on callback function execution until promise is completed

I have some third party library whose events I'm listening. 我有一些第三方库正在监听其事件。 I get a chance to modify data which that library is going to append in the UI. 我有机会修改该库将要添加到UI中的数据。 It is all fine until that data modification is synchronous. 直到数据修改是同步的,一切都很好。 As soon as I involve Ajax callbacks/promises, this fails to work. 一旦涉及Ajax回调/承诺,这将无法正常工作。 Let me put an example to show case the problem. 让我举一个例子来说明问题所在。

Below is how I'm listening to a event:- 以下是我如何收听事件:-

d.on('gotResults', function (data) {

  // If alter data directly it works fine.
  data.title = 'newTitle';
  // Above code alters the text correctly.

  //I want some properties to be grabbed from elsewhere so I make an Ajax call.
  $.ajax('http://someurl...', {data.id}, function (res) {
    data.someProperty = res.thatProperty;
  });
  // Above code doesn't wait for ajax call to complete, it just go away and 
  renders page without data change.


  // Yes I tried promises but doesn't help
  return fetch('http://someurl...').then(function (data) {
    data.someProperty = res.thatProperty;
    return true;
  });
  // Above code also triggers the url and gets away. Doesn't wait for then to complete.

});

I cannot change/alter the third party library. 我无法更改/更改第三方库。 All I have is to listen to event and alter that data. 我所要做的就是听事件并更改数据。

Any better solutions. 任何更好的解决方案。 Nope. 不。 I can't use async/wait, generators, because I want to have it supported for ES5 browsers. 我不能使用异步/等待生成器,因为我想让ES5浏览器支持它。

You cannot make a synchronous function wait for an asynchronous response, it's simply not possible by definition. 您不能让同步函数等待异步响应,从定义上讲根本不可能。 Your options pretty much are: 您的选择几乎是:

  1. BAD IDEA: Make a synchronous AJAX request. 坏主意:发出同步 AJAX请求。 Again: BAD IDEA. 再次: 糟糕的想法。 Not only will this block the entire browser, it is also a deprecated practice and should not be used in new code, or indeed ever. 这不仅会阻塞整个浏览器,而且也是不推荐使用的做法,因此不应在新代码中使用,甚至永远不要使用。

  2. Fetch the asynchronous data first and store it locally, so it's available synchronously when needed. 首先获取异步数据并将其存储在本地,因此在需要时可以同步使用。 That obviously only works if you have an idea what data you'll be needing ahead of time. 显然,这只有在您提前知道将需要哪些数据的情况下才有效。

  3. Alter the 3rd party library to add support for asynchronous callbacks, or request that of the vendor. 更改第3方库,以添加对异步回调的支持,或请求供应商的支持。

  4. Find some hackaround where you'll probably let the library work with incomplete data first and then update it when the asynchronous data is available. 找到一些解决方法,您可以在其中首先使库处理不完整的数据,然后在异步数据可用时对其进行更新。 That obviously depends a lot on the specifics of that library and the task being done. 显然,这在很大程度上取决于该库的细节和正在完成的任务。

Does the gotResults callback function really need to return anything else than true ? gotResults回调函数是否真的需要返回除true以外的其他true If not, then you could just write regular asynchronous code without this library knowing about it. 如果没有,那么您可以在不了解该库的情况下编写常规异步代码。 Let me explain myself by rewriting your pseudocode: 让我通过重写您的伪代码来解释一下自己:

 d.on('gotResults', function (data) { // If alter data directly it works fine. data.title = 'newTitle'; // Above code alters the text correctly. //I want some properties to be grabbed from elsewhere so I make an Ajax call. $.ajax('http://someurl...', {data.id}, function (res) { data.someProperty = res.thatProperty; // Above code doesn't wait for ajax call to complete, it just go away and // EDIT: now it should render properly renders page without data change. // Yes I tried promises but doesn't help return fetch('http://someurl...'); // Above code also triggers the url and gets away. Doesn't wait for then to complete. }).then(function (data) { data.someProperty = res.thatProperty; // maybe render again here? }).catch(function(err) { handleError(err); // handle errors so the don't disappear silently }); return true; // this line runs before any of the above asynchronous code but do we care? }); 

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

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