@TheToolBox आपके लिए एक अच्छा जवाब है।
बस मज़ेदार के लिए, मैं आपको एक वैकल्पिक तकनीक दिखाने जा रहा हूं जो जेनरेटर का उपयोग करता है जो इसकी प्रेरणा coroutines से प्राप्त करता है।
Promise.prototype.bind = Promise.prototype.then;
const coro = g => {
const next = x => {
let {done, value} = g.next(x);
return done ? value : value.bind(next);
}
return next();
}
कि का उपयोग करना, अपने कोड वहाँ कुछ बहुत दिलचस्प बातें आप वादे के साथ जनरेटर का उपयोग कर सकते हैं इस
const addElement = elementText =>
new Promise(resolve => {
setTimeout(() => {
var element = document.createElement('H1');
element.innerText = `${elementText} ${Date.now()}`;
document.body.appendChild(element);
resolve();
}, Math.random() * 2000);
});
coro(function*() {
yield addElement('first');
yield addElement('second');
yield addElement('third');
yield addElement('fourth');
}());
तरह दिखाई देगा। वे यहां तुरंत स्पष्ट नहीं हैं क्योंकि आपके addElement
वादे किसी वास्तविक मूल्य को हल नहीं करता है।
आप वास्तव में resolve
कुछ मान, आप की तरह
// sync
const appendChild = (x,y) => x.appendChild(y);
// sync
const createH1 = text => {
var elem = document.createElement('h1');
elem.innerText = `${text} ${Date.now()}`;
return elem;
};
// async
const delay = f =>
new Promise(resolve => {
setTimeout(() => resolve(f()), Math.random() * 2000);
});
// create generator; this time it has a name and accepts an argument
// mix and match sync/async as needed
function* renderHeadings(target) {
appendChild(target, yield delay(() => createH1('first')));
appendChild(target, yield delay(() => createH1('second')));
appendChild(target, yield delay(() => createH1('third')));
appendChild(target, yield delay(() => createH1('fourth')));
}
// run the generator; set target to document.body
coro(renderHeadings(document.body));
टिप्पण लायक कुछ कर सकते हैं, तो createH1
और appendChild
तुल्यकालिक कार्य हैं। यह दृष्टिकोण आपको प्रभावी रूप से सामान्य कार्यों को एक साथ करने और सिंक के बीच की रेखाओं को धुंधला करने और एसिंक के बीच की रेखाओं को धुंधला करने की अनुमति देता है। यह मूल रूप से आपके द्वारा पोस्ट किए गए कोड की तरह ही निष्पादित/व्यवहार करता है।
तो हाँ, यह अंतिम कोड उदाहरण थोड़ा और दिलचस्प हो सकता है।
अन्त में,
एक विशिष्ट लाभ coroutine .then
श्रृंखलन से अधिक है, कि संकल्प लिया वादे के सभी एक ही दायरे के अंदर पहुँचा जा सकता है है।
.then
जंजीरों ...
op1()
.then(x => op2(x))
.then(y => op3(y)) // cannot read x here
.then(z => lastOp(z)) // cannot read x or y here
coroutine करने के लिए ...
function*() {
let x = yield op1(); // can read x
let y = yield op2(); // can read x and y here
let z = yield op3(); // can read x, y, and z here
lastOp([x,y,z]); // use all 3 values !
}
बेशक
की तुलना में इस वादे का उपयोग कर के लिए workarounds हैं, लेकिन ओह लड़का यह बदसूरत तेजी से प्राप्त करता है ...
यदि आप इस तरह जेनरेटर का उपयोग करने में रुचि रखते हैं, तो मैं आपको सलाह देता हूं कि आप co प्रोजेक्ट चेकआउट करें।
और यहाँ एक लेख, Callbacks vs Coroutines, सह, @tj के निर्माता से है।
वैसे भी, मैं तुम्हें मजा कुछ अन्य तकनीकों के बारे में सीखने की थी आशा ^__^
अपने तीर कार्यों को सरल बनाया जा सकता है - 'तो फिर (x => addElement (" दूसरी "))' - इसी तरह आप 'addElement' में तीर कार्यों का उपयोग किया जा सकता है - लेकिन मुझे यकीन है कि तुम क्यों लगता है कि नहीं कर रहा हूँ आप "नए बंद होने का एक बड़ा सौदा" बना रहे हैं –
मैं इस मुद्दे में भी भाग गया हूं और इसके बजाय 'बाइंड' का उपयोग कर समाप्त हुआ हूं, हालांकि यह गन्दा लगता है (लेकिन अतिरिक्त फ़ंक्शन रैपर से बचाता है): '.then (addElement.bind (शून्य, "दूसरा")) ', आदि –
बस सोच रहा है कि यहां बनाए गए अनावश्यक वादे ऑब्जेक्ट्स हैं या नहीं। आपके जैसे कुछ 6 वादे ऑब्जेक्ट्स बनाते हैं जब 3 पर्याप्त होगा? फिर पहले से ही एक वादा ऑब्जेक्ट बनाता है जिसे आप फिर से उपयोग नहीं कर सकते? मुझे लगता है कि मैं गलत हो सकता है। – Nishant