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

时间:2018-01-17 10:27:17

标签: javascript ajax promise ecmascript-5

我有一些我正在听的事件的第三方图书馆。我有机会修改该库将要附加到UI中的数据。在数据修改是同步的之前一切正常。一旦我涉及Ajax回调/承诺,这就无法工作。让我举一个例子来说明问题。

以下是我正在听一个事件: -

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.

});

我无法更改/更改第三方库。我只需要听取事件并改变数据。

任何更好的解决方案。不。我不能使用异步/等待,生成器,因为我希望它支持ES5浏览器。

2 个答案:

答案 0 :(得分:1)

您不能使同步函数等待异步响应,根据定义它根本不可能。你的选择很多:

  1. BAD IDEA:制作同步 AJAX请求。再一次: BAD IDEA。这不仅会阻止整个浏览器,它也是一种不赞成使用的做法,不应该在新代码中使用,或者确实应该使用。

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

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

  4. 找到一些hackaround,你可能会让这个库首先使用不完整的数据,然后在异步数据可用时更新它。这显然在很大程度上取决于该库的具体情况以及正在完成的任务。

答案 1 :(得分:0)

gotResults回调函数真的需要返回除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?
});