2016-04-12 30 views
0

için bitirmek bekliyorum ben javascript yeniyim ve ben meşgul bitirmek işlev için bekleyen bir sorun var. Burada kod yok ama kısa bir süre açıklayacağız: Ben 100 ms, hatta 10 s infaz edilebilir bir fonksiyonu varJavaScript: Belirli bir zamana

, en başka var Sonra foo1

diyelim İlk başta giriş parametreleriyle çalışan ve sonra Foo1'i çağıran Foo2. Giriş parametrelerinden biri, arasındaki milisaniye cinsinden zaman, fonksiyonun bitmesini beklemek istedim. yürütme bu sınırı aşması durumunda, sadece bitireceğim operasyon yapacak ve dönüş. Foo1 aşan süreden önce tamamlandıktan durumda, önceki dönün.

Benim çözümleri temel kod sözdiziminde burada, ama umarım anlaşılabilir.

// First wait for the specified time and then execute Foo1 - obviously one after another 
self.Foo2 (time) { 
    setTimeout(self.Foo1(),0); 
    var now = new Date().getTime(); 
    while(new Date().getTime() < now + time){ /* do nothing */ }  
} 
/*This one, if I understand it well, creates a queue where at first DoWait 
is executed, then Foo1 and after that all other DoWait - so practically 
we wait the whole time of execution.*/ 

var finished = false; 
self.DoWait(time, now) { 
    if(!finished && (new Date().getTime() < now + time)) { 
     setTimeout(self.DoWait(time, now), 20); 
    } else { 
     /* finish procedure */ 
    } 
} 

self.Foo2 (time) { 
    setTimeout(function() { self.Foo1(); finished=true;},0); 
    var now = new Date().getTime(); 
    self.DoWait(time, now)  
} 

bunu yapmak nasıl mümkün bazı çözüm hakkında biliyor musunuz? çalışanı hakkında okudum, ancak çalışan oluşturmak için, tüm yeni dosyada işleve ihtiyacınız var, ancak işlev/dosya içinde yapılabilecek bir şeyi tercih ederim. Tüm cevaplar için şimdiden teşekkür ederiz.

+0

Çözüm, JavaScript'te meşgul beklemek için değil. – Bergi

+1

'setTimeout (self.Foo1(), 0)' self.Foo1() 'çağırır, bir zaman aşımından sonra değil. 'SetTimeout (Foo1.bind (self), 0) 'yazmanız gerekir. – Barmar

+0

Aslında 'setTimeout (self.Foo1.bind (self), 0)'. – Barmar

cevap

0

Size peşinde olduğun yapacak bir race ile Promises gibi geliyor.

The MDN Docs cover it nicely , ama burada kod çoğaltmak gerekir:

var p1 = new Promise(function(resolve, reject) { 
    setTimeout(resolve, 500, "one"); 
}); 
var p2 = new Promise(function(resolve, reject) { 
    setTimeout(resolve, 100, "two"); 
}); 

Promise.race([p1, p2]).then(function(value) { 
    console.log(value); // "two" 
    // Both resolve, but p2 is faster 
}); 

var p3 = new Promise(function(resolve, reject) { 
    setTimeout(resolve, 100, "three"); 
}); 
var p4 = new Promise(function(resolve, reject) { 
    setTimeout(reject, 500, "four"); 
}); 

Promise.race([p3, p4]).then(function(value) { 
    console.log(value); // "three" 
    // p3 is faster, so it resolves    
}, function(reason) { 
    // Not called 
}); 

var p5 = new Promise(function(resolve, reject) { 
    setTimeout(resolve, 500, "five"); 
}); 
var p6 = new Promise(function(resolve, reject) { 
    setTimeout(reject, 100, "six"); 
}); 

Promise.race([p5, p6]).then(function(value) { 
    // Not called    
}, function(reason) { 
    console.log(reason); // "six" 
    // p6 is faster, so it rejects 
}); 
+0

Denedim, ama işe yaramıyor. Bu iki fonksiyonun bir şekilde paralel olarak çalışmasını istiyorum. Bu Promise.race sadece bu işlevleri sırayla yürütür ve eğer bazıları biterse geri döner. Ama ikisini de bir şekilde "paralel" olarak çalıştırmak istiyorum ve eğer bazıları bittiyse, o zaman tüm işlevi bitirin. – eaten

0

Sen foo2 içinde bir zaman aşımından sonra nihai prosedürü çağırabilirsiniz. Bu zamanaşımı tutamacını Foo1'e geçirebilirsiniz. Eğer Foo1 daha önce yapılırsa, Foo2 tarafından yaratılan zaman aşımını temizleyebilir ve son prosedürü kendisi arayabilir.

self.Foo2 (time) { 
    /* Foo2 stuff */ 
    //call final procedure after set time 
    var timeout = setTimeout(self.finalProcedure, time); 
    //pass timout handle to Foo1 
    self.Foo1(time, timeout); 
} 

self.Foo1 (time, timeout) { 
    var before = new Date().getTime(); 
    /* Foo1 stuff */ 
    var after = new Date().getTime(); 
    if((after - before) < time){ //finished earlier 
     //clear timeout as Foo1 is done 
     clearTimeout(timeout); 
     //call final procedure 
     self.finalProcedure(); 
    } 
} 

self.finalProcedure(){ 
    /* final steps */ 
} 
+0

Evet, ancak Foo1 yürütme zamanı> zamanı durumunda, Foo1 tamamlandıktan sonra belirtilen süre sonunda değil, zaman aşımı gerçekleştirilecektir. – eaten

+0

Gerçekten değil. Foo2, Foo1'i temizlemediği sürece, sonradan çalışacak şekilde ayarladıktan sonra zaman aşımı gerçekleşir. Foo1 hakkında bilmiyor ya da onu bekliyor. –

+0

Ben bu şekilde uyguladım ve bence beklediğim gibi oldu. SetTimeout (self.finalProcedure, time) işlevini sonuna kadar taşıyacak ve self.Foo1 (...) 'ı çalıştıracaktır. Foo1 yürütme süresi çok uzunsa, bitene kadar bekler ve zaman aşımını temizler.Çok iş parçacıklı değil, bu yüzden sadece Foo1 (sadece bir kod satırı) kesmek ve bu zaman aşımı ile çalışmak değil. – eaten

İlgili konular