等待回调函数执行直到 promise 完成

Hold on callback function execution until promise is completed

我有一些第三方库,我正在收听其事件。我有机会修改该库将附加到 UI 中的数据。在数据修改同步之前一切都很好。一旦我涉及 Ajax callbacks/promises,这就不起作用了。让我举个例子来说明问题。

以下是我收听事件的方式:-

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.

});

我不能change/alter第三方库。我所要做的就是监听事件并更改该数据。

有没有更好的解决办法。没有。我不能使用 async/wait 生成器,因为我想让它支持 ES5 浏览器。

您不能让同步函数等待异步响应,根据定义这是不可能的。您的选择几乎是:

  1. 坏主意: 发出 同步 AJAX 请求。再次强调:BAD IDEA。 这不仅会阻塞整个浏览器,而且也是一种已弃用的做法,不应在新代码中使用,甚至永远不应使用。

  2. 首先获取异步数据并将其存储在本地,以便在需要时同步可用。这显然只有在您提前知道需要哪些数据时才有效。

  3. 更改第 3 方库以添加对异步回调的支持,或请求供应商。

  4. 找到一些 hackaround,您可能会先让库处理不完整的数据,然后在异步数据可用时更新它。这显然在很大程度上取决于该库的细节和正在完成的任务。

gotResults 回调函数真的需要 return 除了 true 之外的任何东西吗?如果没有,那么你可以在这个库不知道的情况下编写常规的异步代码。让我通过重写你的伪代码来解释我自己:

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?
});