2015-10-19 11 views
9

का उपयोग करके "टाइमआउट के साथ अंतराल" के लिए एक अच्छा पैटर्न क्या है। मैं प्रत्येक एन एमएस के संसाधन के लिए मतदान करने के लिए कुछ कोड लिख रहा हूं जो एम सेकंड के बाद टाइमआउट होना चाहिए। मैं पूरी बात को ब्लूबर्ड का उपयोग करके जितना संभव हो सके वादा करना चाहता हूं। समाधान जो मैंने अभी तक किया है, नोड के अंतराल, रद्द करने योग्य ब्लूबर्ड वादे और ब्लूबर्ड के टाइमआउट फ़ंक्शन का उपयोग करता है।वादा

मुझे आश्चर्य है कि क्या ब्लूबर्ड के साथ अंतराल को समाप्त करने और सामान्य रूप से वादे करने का बेहतर तरीका है? ज्यादातर यह सुनिश्चित करके कि अंतराल बिंदु पर बंद हो जाता है और कभी भी अनिश्चित काल तक नहीं चलता है।

var Promise = require('bluebird'); 

function poll() { 
    var interval; 

    return new Promise(function(resolve, reject) { 
    // This interval never resolves. Actual implementation could resolve. 
    interval = setInterval(function() { 
     console.log('Polling...') 
    }, 1000).unref(); 
    }) 
    .cancellable() 
    .catch(function(e) { 
     console.log('poll error:', e.name); 
     clearInterval(interval); 
     // Bubble up error 
     throw e; 
    }); 
} 

function pollOrTimeout() { 
    return poll() 
    .then(function() { 
     return Promise.resolve('finished'); 
    }) 
    .timeout(5000) 
    .catch(Promise.TimeoutError, function(e) { 
     return Promise.resolve('timed out'); 
    }) 
    .catch(function(e) { 
     console.log('Got some other error'); 
     throw e; 
    }); 
} 

return pollOrTimeout() 
    .then(function(result) { 
    console.log('Result:', result); 
    }); 

आउटपुट:

Polling... 
Polling... 
Polling... 
Polling... 
poll error: TimeoutError 
Result: timed out 

उत्तर

5

मैं कुछ इस तरह करना होगा -

function poll() { 
    return Promise.resolve().then(function() { 
    console.log('Polling...'); 
    if (conditionA) { 
     return Promise.resolve(); 
    } else if (conditionB) { 
     return Promise.reject("poll error"); 
    } else { 
     return Promise.delay(1000).then(poll); 
    } 
    }) 
    .cancellable() 
} 

इसके अलावा Promise constructor anti-pattern के बारे में पता

+1

अच्छा। आप अंतराल कैसे पूरा करेंगे? एक त्रुटि फेंकने का एकमात्र तरीका लगता है। मुझे पता है कि वादा कन्स्ट्रक्टर एक विरोधी पैटर्न है लेकिन इस मामले में यह फिट लग रहा था (घटनाओं + वादे के साथ ही यह एक और विषय है)। – Chris911

+0

ठीक है अब मैं आपका प्रश्न समझता हूं। मेरा संपादन जांचें। – vinayr

+0

हाँ जो काम करता है। धन्यवाद और स्वीकार्य उत्तर। – Chris911

1

रेने Wooller एक बहुत अच्छी बिंदु बनाता हो:

चेतावनी: दुर्भाग्य से, इस तरह जावास्क्रिप्ट में प्रत्यावर्तन अंत में कॉल स्टैक को परिपूर्ण और स्मृति अपवाद

यहां तक ​​कि अगर यह है अपवाद, इस अंतरिक्ष बर्बाद किया जाता है, और एक अपवाद के जोखिम से बाहर का परिणाम देगा अत्यधिक मतदान विलंब को प्रोत्साहित कर सकता है।

मुझे लगता है कि यह बहुत महत्वपूर्ण setInterval पसंद करते हैं करने के लिए है:

var myPromise = new Promise((resolve, reject) => { 
    var id = window.setInterval(() => { 
     try { 
      if (conditionA) { 
       window.clearInterval(id); 
       resolve("conditionA"); 
      } else if (conditionB) { 
       throw new Error("conditionB!"); 
      } 
     } catch(e) { 
      window.clearInterval(id); 
      reject(e); 
     } 
    }, 1000); 
}); 

कुछ NPM संकुल कि इस आवश्यकता को, जिनमें से मैं promise-waitfor सबसे ज्यादा पसंद को संबोधित कर रहे हैं। यह 38 लाइन लंबी है और नौकरी करता है।

var myPromise = waitFor(() => { 
    if(conditionA) return true; 
    if(conditionB) throw new Error("conditionB!"); 
    return false; 
}); 
+0

क्या आप मुझे समझा सकते हैं कि अगर (कंडीशनए) एक वादा है तो यह कैसे हासिल किया जाएगा? मैं प्रतीक्षाफोर() में एक सरल 'सत्य' या 'झूठी' वापस करने के लिए वादा श्रृंखला से कभी नहीं बच सकता। – NZHammer

+1

'conditionA' एक वादा होने पर एक अलग प्रश्न जोड़ने के लिए स्वतंत्र महसूस करें। शायद समाधान में 'Promise.race' शामिल है। –

+0

मैंने पढ़ा है कि यदि आपके चुनाव में आपके सेटिनवर्वल की तुलना में अधिक समय लगता है, तो यह कतार का निर्माण करेगा। फिर जब यह खत्म हो जाता है, तो उसे कतार को संसाधित करना होता है। और यह कि एक और सेटटाइमआउट को लात मारने के लिए सेटटाइमआउट और रिकर्सन का उपयोग करना बेहतर है। – TamusJRoyce

संबंधित मुद्दे