我正在使用javascript并使用Promises
进行编程,现在使用Q.js
。我终于明白我理解自己在做什么,但是我遇到了特定行为的困难时期。
我有一种情况,我有相似的代码重复几次。它基本上就是这样......
{
// start
var deferred = Q.defer();
// do something {
deferred.resolve();
}
return deferred.promise;
}
好的,这一切都很好,但每次都重复这一切都很烦人,所以我试图把它包装成一些东西。这只是一个示例,它不是整个javascript文件,因为大多数其他部分都不相关。
{
var list = [];
queue = function(f) {
var deferred = Q.defer();
list.push(f(deferred));
return deferred.promise;
}
{
queue(function(deferred){
// do some work
// we want the deferred here so we can resolve it at the correct time
deferred.resolve();
});
}
}
问题是我不想让它在我排队的瞬间运行。我基本上想要构建列表,然后再运行它。我使用reduce
Q.js
函数运行列表
{
return list.reduce(function(i, f) {
return i.then(f);
}, Q());
}
但这与我的目标背道而驰,因为我真的不打算在他们排队的同时运行它们。有没有办法保存执行以便以后仍然通过函数传递延迟对象?
我被问到我期望代码做什么,这是一个公平的问题。我会试着解释一下。这样做的目的是拆分逻辑因为我使用ASP.NET MVC
,所以我有_Layout
个页面,然后是普通视图 - 所以有些逻辑在其他事情完成之前无法运行,但是有时是每页一次。设计这种方法是为了解决这个问题。
基本上它就像这样......
由于缺乏更好的术语或当前实现,这是一个全局对象。我计划最终改变这一点,但一步一步。
{
var Loader = {};
var list = [];
initialize = function() {
Q().then(step1).then(step2).then(process).then(finalStep);
};
queue = function(f) {
// push the given function to the list
};
process = function() {
return list.reduce(function(i,f){
return i.then(f);
}, Q());
};
step1 = function() { // generic example
// create a promise
return deferred.promise;
}; // other steps are similar to this.
return Loader;
}
<head>
@RenderSection("scripts", false)
<script type="text/javascript">
// we have the loader object already
Loader.initialize();
</script>
</head>
@section Scripts {
<script type="text/javascript">
Loader.promise(function(deferred){
// do something here.
deferred.resolve();
}));
</script>
}
答案 0 :(得分:6)
你可以使用一个闭包。
queue(function(deferred) {
return function() {
// this is the actual function that will be run,
// but it will have access to the deferred variable
deferred.resolve();
};
});
答案 1 :(得分:1)
我认为你应该做点什么
var Loader = {
promise: function(construct) {
var deferred = Q.defer();
construct(deferred);
return deferred.promise;
},
queue: function(f) {
this.ready = this.ready.then(f);
},
ready: Q.Promise(function(resolve) {
window.onload = resolve; // or whatever you need to do here
// or assign the resolve function to Loader.initialize and call it later
})
};
然后Loader.queue()
返回其他承诺的函数。