Coding的时候遇到一些需要保证执行顺序的回调,用了Promise来写,总结下自己的理解和踩的坑
更新
下面 promise 的写法ok,但是promise的调用是异步的,并不能保证执行顺序
场景
渲染一个动态数据列表,列表上有图片轮播
定义了三个方法
getListData : function(){
var me = this;
//忽略ajax的写法,这里用了插件
me.ajax({
url: '/Takeout/src/data/shopList.json'
}).done(function (data) {
resolve(data);
})
},
showList : function(data){
//将数据渲染到列表,要使用 getListData() 里拿到的数据
//由于使用的组件问题,dom结构在这里才加载,就是说,要等这个方法执行完,图片轮播的组件才能找到容器
},
switchable : function(){
//加载图片轮播组件
}
初始化后执行顺序:
getListData –> showList –> switchable
开始的想法
用 Promise.resolve()
把getListData()
变成一个thenable对象,然后链式调用
Promise.resolve(me.getListData())
.then(function(){
me.showList();
}).then(function(){
me.switchable();
});
结果当然是失败了,me.showList()
并没有等me.getListData()
执行完才执行,所以列表没有数据
失败原因
Promise.resolve()方法接受的参数有三种
- 数据对象
- Promise对象
- 具有then方法的对象(thenable对象)
然而,me.getListData()方法没有返回东西,即返回的是undefined
所以 me.showList()就不能保证在 me.getListData() 后执行了
解决方案
init : {
getListData : function(){
var me = this;
return new Promise(function(resolve, reject) {
me.ajax(
// ···
);
},
showList : function(data){
var me = this;
QApp.showWidget(
// ···
);
},
switchable : function(){
var me = this;
return QApp.showWidget(
// ···
);
}
},
ready : function(){
var me = this;
me.getListData().then(function(data) {
me.showList(data.shopInfo);
}).then(function(widget) {
me.switchable();
}).catch(function() {
console.error('error');
})
}