嗨,我有这样简单的代码:
jQuery(function ($) {
function Item(val) {
this.val = val
var self = this;
this.generateTrDOM = function () {
var tr = '<tr>';
tr += '<td>' + self.val + '</td>';
tr += '</tr>';
return tr;
};
}
function ItemsCollection() {
this.someHandler = $('#some_table_id');
this.data = [];
var self = this;
this.getData = function () {
return new Promise(function (resolve, reject) {
$.post(base_url + 'controller/action', {
action_type: 'get_items'
}, function (data) {
self.prepareData(data).then(resolve());
}, "json");
});
};
this.prepareData = function (data) {
return new Promise(function (resolve, reject) {
for (var x = 0; x < data.length; x++) {
self.data.push(
new Item(data[x])
);
}
});
};
this.updateTable = function () {
for (var x = 0; x < self.data.length; x++) {
self.someHandler.append(self.data[x].generateTrDOM());
}
};
}
var data = new ItemsCollection();
data.getData() //this is done second
.then(
data.updateTable(); //this is done first - i dont not want to
);
});
我希望 data.updateTable()发生在AJAX请求之后的 data.getData()之后,但是之前的启动。我读到了关于承诺的内容,而在我的其他项目中,它的效果非常好。
我不明白。谢谢你的一些建议。
答案 0 :(得分:2)
这应该可以解决问题。正如jfriend00所说,你必须将函数引用传递给then(..)。如果将data.updateTable()传递给then(..),则立即执行该函数。
var data = new ItemsCollection();
data.getData()
.then(data.updateTable);
答案 1 :(得分:1)
尽量避免使用嵌套的promises来保持异步代码的线性。
查看这篇文章:Are nested promises normal in node.js?(我知道这不是节点,但它的想法是相同的:P)
要执行此操作,您需要致电getData
,解决问题,然后致电prepareData
并解决,然后updateTable
如下:
jQuery(function ($) {
function Item(val) {
this.val = val
var self = this;
this.generateTrDOM = function () {
var tr = '<tr>';
tr += '<td>' + self.val + '</td>';
tr += '</tr>';
return tr;
};
}
function ItemsCollection() {
this.someHandler = $('#some_table_id');
this.data = [];
var self = this;
this.getData = function () {
return new Promise(function (resolve, reject) {
$.post(base_url + 'controller/action', {
action_type: 'get_items'
}, function (data) {
resolve(data);
}, "json");
});
};
this.prepareData = function (data) {
return new Promise(function (resolve, reject) {
for (var x = 0; x < data.length; x++) {
self.data.push(
new Item(data[x])
);
}
resolve(self.data);
});
};
this.updateTable = function (data) {
for (var x = 0; x < self.data.length; x++) {
self.someHandler.append(data[x].generateTrDOM());
}
};
}
var data = new ItemsCollection();
data.getData()
.then((result) => {
return data.prepareData(result);
})
.then((prearedData) => {
return data.updateTable(prearedData);
});
});
这是https://jsfiddle.net/aejvsxke/5/的工作小提琴(我将$post
替换为$.get
假冒api并在每个函数中添加console.log
用于测试目的,因此您可以看到执行的顺序)
使用它来比较两个代码并查看差异:https://www.diffchecker.com/diff
提示:对于this.getData
,你可以直接返回$.post
,因为它返回一个promise本身(不需要在promise中包装它,也不需要回调)从 jQuery 1.5开始:https://api.jquery.com/jquery.post/
所以它变成了这样:
this.getData = function () {
return $.post(base_url + 'controller/action', {
action_type: 'get_items'
}, "json");
};
我希望re
解决你的问题;或者至少给你一个想法:P