如果我们在javascript中有两个功能,一个慢,一个快。例如:
function slow() {
setTimeout(function() {console.log("slow finished")}, 10000);
}
function fast() {
console.log("fast");
}
这些功能并没有像promisses那样有新的结构(如果我们之后没有实现的话)。
我们如何强制按顺序运行这些功能?例如:
function run() {
slow();
fast();
}
run();
我们如何强制快速等待慢结束? 我正在寻找可以在移动应用程序浏览器中运行的解决方案,因为我的Apache Cordova项目。
有办法做到这一点吗?
我的想法是在函数之间注入回调函数。 并且在慢速函数结束时调用此回调,调用快速函数。
重要的是我无法(或不会)重写慢和快速功能的代码, 因为它们将驻留在外部库中。
我正在寻找一种解决方案,将这个问题视为外部观察员和经理。
我们怎么做?
修改
他试图解决合并答案的问题。还没有成功。 我已经改变了慢,但实际上并不允许这样做。我已将其更改为 a 正在发生的事情。我无法获得有趣的内容,因为 a 会立即变为未定义,而不会在慢结束后...
var a = "adsfadsfadsf";
function slow() {
setTimeout(function() {console.log("slow done"); console.log("a2", window.a);}, 3000);
}
function fast() {
console.log("a3", window.a);
console.log("fast done");
}
var newSlow = function() {
return new Promise(function(resolve, reject){
window.a = slow();
console.log("a", a);
resolve("Sucess");
});
};
newSlow().then(function(resolve){fast();}, function(reject){console.log("error");});
我试过解决(慢()); 也没有成功。
答案 0 :(得分:2)
这是一个非常有趣的问题。好吧,我可以想到一种方法,如果它将某个全局变量“g”改为某个值,则说“true”。在这种情况下,如果您可以按顺序运行它们,
<script>
var g = false;
var i;
function slow() {
setTimeout(function() {console.log("slow finished");g=true;}, 10000);
}
function fast() {
console.log("fast");
}
function run() {
slow();
i = setInterval(function(){check();},1000);
}
function check(){
if(g){
fast();
clearInterval(i);
}
}
run();
</script>
更新:有些事情让我感到震惊,我想我们可以向slow()
添加回调函数,即使我们无法直接访问它。
如果在没有括号的情况下调用函数,那么整个函数作为内容将作为字符串返回,因此我们可以通过添加fast()
来编辑该字符串,并使用eval()
将该字符串注册为函数。
function run() {
var myFun = slow+"";
myFun = myFun.substring(0,myFun.length-1);
alert(myFun);
myFun += "fast();}";
//to register the string "myFun" as a function
eval(myFun);
slow();
}
基本上我们的slow()
函数变为,
function slow(){
//function code
//the appended function
fast();
}
注意:这在上面给出的示例中不起作用,其中GarouDan故意添加了setTimeout限制来重新创建slow()
函数花费的时间比fast()
更长的情况功能。但是,在现实世界的情况下,我确信这种方法肯定会起作用。
答案 1 :(得分:1)
您可以使用Promise模式。
Promise是针对代码的各个部分可能在不可知的时间内(或根本不完整)运行缓慢或快速或完成的情况而定制的,同时仍然为您提供执行控制。
我个人最喜欢的实现Promise模式的库是RSVP。
这是一些伪代码给你的想法。运行可能需要很长时间的操作,然后仅在第一个操作完成时运行一个操作,或者处理它失败。
function doFoo() {
var promise = new RSVP.Promise(function(resolve, reject) {
// do some long-running operation, like retrieve
// data from a slow site...
if (data.Status && data.Status === 200) {
resolve(data);
} else {
reject(data.Error)
}
});
return promise;
}
function doBar() {
var promise = new RSVP.Promise(function(resolve, reject) {
// do some fast operation, like count to 10
for (i = 0; i < 10; i++) {
console.log(i);
}
resolve("");
});
return promise;
}
现在你可以致电:
function inOrder() {
doFoo().then(function(success) {
doBar();
}).catch (function(failure) {
console.log("oops! " + failure);
}
});
}
这会运行doFoo,并且只在doFoo成功完成后运行doBar。请注意,即使doFoo失败,您也可以运行doBar。