2015-07-29 9 views
18

अगर मैं यूआरएल की एक सरणी है:मैं Promise.all के साथ URL की सरणी कैसे प्राप्त कर सकता हूं?

var urls = ['1.txt', '2.txt', '3.txt']; // these text files contain "one", "two", "three", respectively. 

और मैं एक वस्तु है कि इस तरह दिखता है का निर्माण करना चाहते:

var text = ['one', 'two', 'three']; 

मैं fetch के साथ ऐसा करना, जानने की कोशिश कर रहा है जो बेशक Promise एस देता है।

कुछ बातें मैं कोशिश की है कि ऐसा नहीं काम:

var promises = urls.map(url => fetch(url)); 
var texts = []; 
Promise.all(promises) 
    .then(results => { 
    results.forEach(result => result.text()).then(t => texts.push(t)) 
    }) 

यह सही नहीं लगता है, और किसी भी मामले में यह काम नहीं करता है - मैं एक साथ न करना पड़े सरणी ['एक', 'दो', 'तीन']।

Promise.all का उपयोग कर सही दृष्टिकोण यहां है?

+0

यह एक bracketing गलती की तरह दिखता है। क्या आप वास्तव में '.forEach (...)' के वापसी मूल्य पर '.then' को कॉल करना चाहते हैं, या बल्कि '... .text()' पर? – Bergi

+0

आप कहां/ग्रंथों को लॉग करते हैं और इसे अभी भी खाली मानते हैं? – Bergi

उत्तर

39

हाँ, Promise.all सही दृष्टिकोण है, लेकिन आप वास्तव में इसे दो बार की जरूरत है अगर आप पहले fetch करने के लिए सभी यूआरएल चाहते हैं और फिर उन लोगों से सभी text रों मिल (जो फिर से प्रतिक्रिया के शरीर के लिए वादे कर रहे हैं)। तो तुम

Promise.all(urls.map(fetch)).then(responses => 
    Promise.all(responses.map(res => res.text()) 
).then(texts => { 
    … 
}) 

करने के लिए आपके वर्तमान कोड काम नहीं कर रहा आवश्यकता होगी क्योंकि forEach रिटर्न कुछ भी नहीं (न तो एक सरणी है और न ही एक वादा)।

बेशक आपको लगता है कि आसान बनाने और सही पूरा संबंधित लाने वादा के बाद प्रत्येक प्रतिक्रिया से शरीर हो रही के साथ शुरू कर सकते हैं:

Promise.all(urls.map(url => 
    fetch(url).then(resp => resp.text()) 
)).then(texts => { 
    … 
}) 
+3

प्रश्न में मुझे कुछ पता चला: आप जावास्क्रिप्ट में एसिंक कैसे काम करते हैं, इसके परिणामस्वरूप आप परिणामों को "निकालने" नहीं कर सकते हैं, लेकिन आप जेनरेटर या एसिंक/इसका अनुकरण करने के लिए प्रतीक्षा कर सकते हैं। जेएस में एसिंक्रोनिसिटी पर एक पूर्ण मार्गदर्शिका के लिए [यह उत्तर] देखें (http://stackoverflow.com/a/30180679/1348195)। –

+0

यह आश्चर्यजनक लग रहा है! लेकिन मैं अपने सिर को चारों ओर लपेट नहीं सकता :(जावास्क्रिप्ट एक अजीब भाषा है – yota

12

न की किसी कारण Bergi के उदाहरण मेरे लिए काम किया है। यह मुझे खाली परिणाम देगा। कुछ डीबगिंग के बाद ऐसा प्रतीत होता है कि लाने से पहले वादा वापस आ जाएगा, इसलिए खाली परिणाम।

हालांकि, बेंजामिन ग्रुनेबाम का जवाब यहां पहले था, लेकिन इसे हटा दिया गया। उनकी विधि ने मेरे लिए काम किया था, इसलिए मैं इसे यहां पहले कॉपी के साथ किसी भी समस्या में भाग लेने के मामले में इसे वैकल्पिक रूप से कॉपी-पेस्ट कर दूंगा।

var promises = urls.map(url => fetch(url).then(y => y.text())); 
Promise.all(promises).then(results => { 
    // do something with results. 
}); 
3

आप map बजाय forEach उपयोग करना चाहिए:

Promise.all(urls.map(url => fetch(url))) 
.then(resp => Promise.all(resp.map(r => r.text()))) 
.then(result => { 
    // ... 
}); 
संबंधित मुद्दे