我想接受RSVP全局对象,并将其包装到我的全局应用程序闭包中的闭包中,这样我就可以按照我想要的方式调用它。它还使我更容易记住如何使用它,以后在开发中。
以下是一些背景知识:RSVP library和a promise tutorial using it。
所以给定RSVP的这个标准用法:
new RSVP.Promise(function(resolve, reject) {
// succeed
resolve(value);
// or reject
reject(error);
});
如何使用您在下面看到的设计模式为此创建包装器?我想把这个RSVP对象放到包装器中,这样我就不必每次都在同一个地方实例化一个新的RSVP Promise并定义我的回调。
我希望每次想要做出新的承诺时,只需致电var newPromise = app.core.promise(callback)
。
如何将它包装成一个闭包以便可能?这就是我到目前为止 - 正确的方法是什么?
app.core.promise = function (resolveFunc, paramObj) {
if(typeof(resolveFunc) === 'function'){
//lets move on shall we?
return new window.RSVP.Promise(function(resolveFunc, reject){
//so this is the real question, what am i to do here?
if(paramObj){
//do something with this object first, or just run it, depending on your use case
//paramObj = chopBalls(paramObj);
resolveFunc(paramObj);
} else {
resolveFunc();
}
reject(error);
});
}
};
我意识到这样做几乎没有理由,但看看我将它们链接在下面的很酷的方式 - 我认为这是值得的。
然后我可以在下面做这个来制作链条,我认为这对我需要的东西来说更清洁,这将是很棒的,这是我的目标!
var chain1, chain2;
chain1 = app.core.promise(someSuccesCallback);
chain1.then(function(){
nowDoAChain1Operation();
}) ;
chain1.then(function(){
nowFollowupOnChain1();
}) ;
chain1.catch(function(error){
throw "we DO have an exception my friends in Chain1. This is the master catch for the chain1. Error object:" + error;
});
chain2 = app.core.promise(aChain2OperationFunction);
chain2.then(function(){
anotherChain2Function();
}) ;
chain2.catch(function(error){
throw "we DO have an exception my friends, in Chin2! This is a master catch for the chain2. Error object:" + error;
});
它看起来很熟悉吗?这是标准延迟的使用方式,这是我试图模仿的方式,因为我已经使用标准的jQuery Deferreds一段时间了,并取得了巨大的成功。
app.core.promise = function(){
return $.Deferred(); //ajax call promise
};
我是否有可能在不打败目的的情况下做什么? (这是我为应用程序选择的设计模式。设计模式是否有意义?)。
编辑代码更新@Benjamin,
所以我想在这里发布我的更改,看看这是否正确。请注意我如何在这里做最后3次返回。这在所有情况下都是必要的吗?不对?它只取决于你在最后一次返回后是否需要承诺,或者响应完成了吗?或者,总是需要返回?即使在render方法中推出了自己的html响应?这是例如代码..
//app.core.js
app.core.promise = function () {
//lets move on shall we?
return window.RSVP.Promise.resolve();
};
//app.ui.js
app.ui.showAmazonResults = function(){
var promiseChain = app.core.promise(); //setup the promise
promiseChain = promiseChain.then(function(){
return app.ui.getSelectedIds(); //this runs a static function that might have a slow iteration
});
promiseChain = promiseChain.then(function(ids){
app.ui.selectedIds = ids; //just sets up a final property needed by the next call.
return app.convertData(); //this guy finishes the processing and setting up all the needed data fore the next call.
});
promiseChain = promiseChain.then(function(data){
//all properties are clean and ready to be posted, run the 3rd party call..
return app.amazon.fetchApi(); //this guy runs an api call out to a 3rd party
});
promiseChain = promiseChain.then( function(amazonData){
//app.amazon.renderData(amazonData); //important to pass in null page here, so the dashboard and old results doesn't disappear on showing more results
return app.amazon.renderData(amazonData); // this guy just renders this up front as rendered html, to the view. so i dont know it needs to be returned
});
promiseChain = promiseChain.catch(function(errorResponse){
//app.helper.log(errorResponse, 'myPage.this_ajax_call');
return app.helper.log(errorResponse, 'myPage.this_ajax_call');
});
return promiseChain; //this entire methods jobs is to completly process and do the dirty work for the cals above, and also renders, so i dont know that this eitehr needs to be returned, since its parent may not need this converted to a promise. or does it for whatever reason?
};
//somewhere inside an onready or init, where events are setup for the app all you need is after a user checks off items, then the following is ran on submit..
app.ui.showAmazonResults();
这就是我使用它的方式。
答案 0 :(得分:5)
嗯,承诺都是关于返回值。
当你这样做时:
chain1.then(function(){
nowFollowupOnChain1();
});
你没有将承诺链接起来而不是等待nowFollowupOnChain1
内的操作 - 相反,你正在分支链。您可能想要做的是使用返回值并将承诺链接起来:
chain1 = chain1.then(function(){
return nowFollowupOnChain1();
});
现在,任何then
chain1
的{{1}}将等待操作首先完成。这是链接点。您通常应该convert whatever callback API you're using to return promises,然后从那时起很少调用promise构造函数。完成后you can enjoy chaining which will take care of most of those issues for you。
如果您想在RSVP中创建一个空的已解决的承诺,您可以随时调用RSVP.Promise.resolve()
,这将返回一个结算RSVP承诺。您也可以像RSVP.defer()
一样在jQuery中执行$.Deferred()
,但我强烈建议您$.Deferred
sort of misses the point of promises以后反对它。
另外,请考虑不要扔弦,它们不会有堆叠痕迹,会让你的生活变得非常困难:)