正如我的代码所示,我目前正在向一个承诺传递两个异步回调函数(成功和回调)。我认为应该可以这样做,但我还没有找到其他办法。
这是我创建承诺的函数,并等待所有这些完成:
_onModelLoaded: function(model) {
var promises = [];
_.each(this._customRecords, function(defect, index) {
promises.push(this._getHistory(model, defect));
}, this);
Deft.Promise.all(promises).then({
success: function(something) {
console.log('woot',something);
}
});
},
_getHistory
函数创建一个promise,然后将它传递给两个函数(_onHistoryLoaded和_onRevisionsLoaded),这样一旦运行了这些回调,promise就会得到解决:
_getHistory: function(model,defect) {
var deferred = Ext.create('Deft.promise.Deferred');
model.load(Rally.util.Ref.getOidFromRef(defect.RevisionHistory), {
scope: this,
success: function(record) {
this._onHistoryLoaded(defect, record, deferred);
}
});
return deferred.promise;
},
_onHistoryLoaded: function(defect, record, def) {
record.getCollection('Revisions').load({
fetch: ['RevisionNumber', 'CreationDate', 'User', 'Description'],
scope: this,
callback: function(revisions) {
this._onRevisionsLoaded(revisions, defect, def);
}
});
},
_onRevisionsLoaded: function(revisions, defect, def) {
_.each(revisions, function(revision, revisionIndex) {
// Do stuff with each revision
}, this);
def.resolve(defect);
},
我不一定需要通过承诺传递最终缺陷,我只是将它放在resolve语句中进行测试。
注意:我的代码运行正常,我只是在寻求简化。
有没有办法避免创建一个承诺,只是通过几个异步函数传递它才能解决它?
答案 0 :(得分:2)
我将尝试提供一些有用的提示,但首先要注意几点。
我对你要解决的领域问题一无所知,这使得很难确定事物的最佳名称,或者确切地说每个功能单元适合于宏观方案。< / p>
您正在使用的库似乎不支持Promise / A +和下一版JavaScript中使用的Promise API。您可以在http://promisesaplus.com/阅读真实承诺的规范,并在http://www.promisejs.org/implementations/
我会尝试编写代码,因为我会用“Promise”编写代码,这是第一个实现,也是我自己编写的代码。
由于onHistoryLoaded实际上是一个异步操作,因此将其名称更改为它执行的操作并让它返回一个promise。对onRevisionsLoaded
执行相同操作,并使getHistory
只执行一项工作:
_onModelLoaded: function(model) {
var promises = _.map(this._customRecords, function(defect, index) {
this._getHistoryRevisions(model, defect).then(function (revisions) {
_.each(revisions, function (revision, revisionIndex) {
// Do stuff wich each revision
}, this);
}.bind(this));
}, this);
Promise.all(promises).done(function(something) {
console.log('woot',something);
});
},
_getHistoryRevisions: function (model, defect) {
return this._getHistory(model, defect).then(function (record) {
return this._getRevisions(record);
}.bind(this));
},
_getHistory: function(model, defect) {
return new Promise(function (resolve, reject) {
model.load(Rally.util.Ref.getOidFromRef(defect.RevisionHistory), {
scope: this,
success: function(record) {
resolve(record);
}
});
}.bind(this));
},
_getRevisions: function(record) {
return new Promise(function (resolve, reject) {
record.getCollection('Revisions').load({
fetch: ['RevisionNumber', 'CreationDate', 'User', 'Description'],
scope: this,
callback: function(revisions) {
resolve(revisions);
}
});
}.bind(this));
}
只要有可能,最好在他们做的事情之后命名这些函数,而不是导致它们的原因。它们不应该真正需要与它们之前或之后发生的事情相结合。承诺背后的大部分想法是,它使我更容易回到我调用函数的编程的同步模型,它做了一件事,然后返回一个值。函数对其使用位置的认识越少,在其他地方重用的越容易:)
答案 1 :(得分:0)
@ForbesLindesay提供的答案非常有用。但是,我使用的是Deft 0.8.0,因此这些承诺的实施存在一些差异。以下是我如何让链条起作用:
_onModelLoaded: function(model) {
var promises = [];
_.each(this._customRecords, function(defect, index) {
promises.push(this._getHistoryRevisions(model, defect).then(function (revisions) {
// do stuff with revisions
}.bind(this)));
}, this);
Deft.Promise.all(promises).then(function(something) {
console.log('woot',something);
}.bind(this));
},
_getHistoryRevisions: function (model, defect) {
return this._getHistory(model, defect).then(function (record) {
return this._getRevisions(record);
}.bind(this));
},
_getHistory: function (model, defect) {
var deferred = Ext.create('Deft.promise.Deferred');
model.load(Rally.util.Ref.getOidFromRef(defect.RevisionHistory), {
scope: this,
success: function(record) {
deferred.resolve(record);
}
});
return deferred;
},
// grabbing the revisions for each defect
_getRevisions: function(record) {
var deferred = Ext.create('Deft.promise.Deferred');
record.getCollection('Revisions').load({
fetch: ['RevisionNumber', 'CreationDate', 'User', 'Description'],
scope: this,
callback: function(revisions) {
deferred.resolve(revisions);
}
});
return deferred;
},
主要区别来自最后两个函数_getHistory
和_getRevisions
- 我不得不创建一个new Promise(...)
的延迟对象而不是Ext.create('Deft.promise.Deferred');
来返回并在回调中解决。
希望这可以帮助其他人解决使用旧版DeftJS
的问题