我有一些我正在听的事件的第三方图书馆。我有机会修改该库将要附加到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浏览器。
答案 0 :(得分:1)
您不能使同步函数等待异步响应,根据定义它根本不可能。你的选择很多:
BAD IDEA:制作同步 AJAX请求。再一次: BAD IDEA。这不仅会阻止整个浏览器,它也是一种不赞成使用的做法,不应该在新代码中使用,或者确实应该使用。
首先获取异步数据并将其存储在本地,以便在需要时同步使用。这显然只有在你知道你提前需要什么数据时才有效。
更改第三方库以添加对异步回调的支持,或请求供应商的支持。
找到一些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?
});