क्या वादे पूरे हो सकते हैं?


127

मैं यहाँ युक्ति का पालन ​​कर रहा हूँ और मुझे यकीन नहीं है कि क्या यह onFulfilled को कई तर्कों के साथ बुलाया जा सकता है। उदाहरण के लिए:

promise = new Promise(function(onFulfilled, onRejected){
    onFulfilled('arg1', 'arg2');
})

ऐसा है कि मेरा कोड:

promise.then(function(arg1, arg2){
    // ....
});

दोनों arg1और प्राप्त होगा arg2?

मुझे इस बात की कोई परवाह नहीं है कि कोई भी विशिष्ट वादे कैसे लागू होते हैं, मैं वादों के लिए w3c कल्पना का पालन करना चाहता हूं।


एक संकेत के रूप में, मैंने पाया कि github.com/then/promise (जो एक
नंगे स्वर का

2
आप .bread के साथ Bluebird का उपयोग करना चाहते हैं। - भी कल्पना के बारे में रोक देखभाल, कल्पना के बारे में इंटरॉप कार्यान्वयन के बीच और डिजाइन द्वारा न्यूनतम है।
बेंजामिन ग्रुएनबाम

जवाबों:


130

मैं यहाँ युक्ति का पालन कर रहा हूँ और मुझे यकीन नहीं है कि क्या यह onFulfilled को कई तर्कों के साथ बुलाया जा सकता है।

नहीं, बस पहला पैरामीटर वादा निर्माता में संकल्प मूल्य के रूप में माना जाएगा। आप एक वस्तु या सरणी की तरह एक संयुक्त मूल्य के साथ हल कर सकते हैं।

मुझे इस बात की कोई परवाह नहीं है कि कोई भी विशिष्ट वादे कैसे लागू होते हैं, मैं वादों के लिए w3c कल्पना का पालन करना चाहता हूं।

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

Promise.try(function(){
    return ["Hello","World","!"];
}).spread(function(a,b,c){
    console.log(a,b+c); // "Hello World!";
});

ब्लूबर्ड के साथ । एक समाधान यदि आप चाहते हैं कि यह कार्यक्षमता इसे पॉलीफ़िल करना है।

if (!Promise.prototype.spread) {
    Promise.prototype.spread = function (fn) {
        return this.then(function (args) {
            return Promise.all(args); // wait for all
        }).then(function(args){
         //this is always undefined in A+ complaint, but just in case
            return fn.apply(this, args); 
        });
    };
}

इससे आप कर सकते हैं:

Promise.resolve(null).then(function(){
    return ["Hello","World","!"]; 
}).spread(function(a,b,c){
    console.log(a,b+c);    
});

आराम से देशी वादे के साथ बेला । या ब्राउज़र में अब (२०१place) आम बात फैल का उपयोग करें:

Promise.resolve(["Hello","World","!"]).then(([a,b,c]) => {
  console.log(a,b+c);    
});

या प्रतीक्षा के साथ:

let [a, b, c] = await Promise.resolve(['hello', 'world', '!']);

2
ध्यान दें कि अन्य परिवादियों (जैसे क्यू) भी .spreadब्लूबर्ड की तरह समर्थन करते हैं - इसका कारण यह नहीं है कि कल्पना को न्यूनतम रखना कोड और पुस्तकालयों के बीच अंतर को अनुमति देने के लिए वास्तव में एक बड़ी बात है।
बेंजामिन ग्रुएनबाम

दूसरा नोट - आप Promise.allफ़ंक्शन को लागू करने से पहले सरणी पर कॉल कर सकते हैं , बजाय .thenइसके कि यह केवल कुछ चीनी पुस्तकालयों को प्रदान करने के लिए संभाल सके। यह अनिवार्य नहीं है, लेकिन यह प्यारा है।
बेंजामिन ग्रुएनबाम

1
Promies.all आपके कार्यान्वयन के लिए अनिवार्य है, हालाँकि आप कार्यान्वयन को बदल सकते हैंreturn Promise.all(args).then(function(args){return fn.apply(this, args);})
Esailija

14
spreadएक स्टॉपगैप है। ES6 विनाशकारी और बाकी / प्रसार ऑपरेटर का परिचय देता है, जो spreadएकमुश्त आवश्यकता को समाप्त करता है । .then(([a, b, c]) => {})
क्रिश कोवल

3
@KrisKowal कि .spread नोट () परोक्ष सब के सब (करता है) लेकिन ES6 destructuring वाक्य रचना नहीं है -> bluebirdjs.com/docs/api/spread.html
Gomino

66

आप E6 विनाशकारी उपयोग कर सकते हैं:

वस्तु विनाशकारी:

promise = new Promise(function(onFulfilled, onRejected){
    onFulfilled({arg1: value1, arg2: value2});
})

promise.then(({arg1, arg2}) => {
    // ....
});

एरे विनाशकारी:

promise = new Promise(function(onFulfilled, onRejected){
    onFulfilled([value1, value2]);
})

promise.then(([arg1, arg2]) => {
    // ....
});

3
एक उदाहरण इस उत्तर के साथ अच्छा और उपयोगी होगा !
राहुल वर्मा

19

किसी वादे की पूर्ति मूल्य एक फ़ंक्शन के रिटर्न मूल्य और एक वादे के अस्वीकृति कारण को एक फ़ंक्शन के फेंके गए अपवाद को समानता देता है। फ़ंक्शंस एकाधिक मान नहीं लौटा सकते हैं, इसलिए वादों में 1 पूर्ति मूल्य से अधिक नहीं होना चाहिए।


4

जहाँ तक मैं ईएस 6 प्रॉमिस विनिर्देश को पढ़कर बता सकता हूं और मानक वादा विनिर्देश इस मामले को लागू करने से रोकने में कोई रोक नहीं लगाता है - हालांकि इसके निम्नलिखित पुस्तकालयों में लागू नहीं किया गया है:

मुझे लगता है कि उनके लिए मल्टी आर्ग रेजॉल्यूशन को छोड़ने का कारण बदलते क्रम को अधिक सक्सेस बनाना है (जैसे कि आप किसी फ़ंक्शन में केवल एक मान लौटा सकते हैं, यह नियंत्रण प्रवाह को कम सहज बना देगा) उदाहरण:

new Promise(function(resolve, reject) {
   return resolve(5, 4);
})
.then(function(x,y) {
   console.log(y);
   return x; //we can only return 1 value here so the next then will only have 1 argument
})
.then(function(x,y) {
    console.log(y);
});

8
क्यू बहु-मूल्य प्रस्तावों का समर्थन नहीं करता है क्योंकि वादे फ़ंक्शन कॉल के परिणाम के लिए प्रॉक्सी के रूप में कार्य करते हैं लेकिन दूरस्थ वस्तुओं के लिए भी प्रॉक्सी कर सकते हैं। इन दोनों मामलों में, एक सरणी एक यौगिक मूल्य का एकमात्र समझदार प्रतिनिधित्व है। ES6 में विनाशकारी और "प्रसार" तर्कों के जोड़ के साथ, वाक्यविन्यास वास्तव में अच्छा हो जाता है। "प्रसार" विधि एक स्टॉपगैप है।
क्रिश कोवल

ठीक है, आप हमेशा कॉलबैक return Promise.of(x, y)से एक स्केलर मान के बजाय कर सकते हैं then
बरगी

2

यहाँ एक CoffeeScript समाधान है।

मैं एक ही समाधान की तलाश कर रहा था और इस जवाब से बहुत अंतरविरोधी पाया गया: AngularJS में कई तर्कों (जैसे $ http) के साथ वादे को खारिज करना

इस आदमी फ्लोरियन का जवाब

promise = deferred.promise

promise.success = (fn) ->
  promise.then (data) ->
   fn(data.payload, data.status, {additional: 42})
  return promise

promise.error = (fn) ->
  promise.then null, (err) ->
    fn(err)
  return promise

return promise 

और इसका उपयोग करने के लिए:

service.get().success (arg1, arg2, arg3) ->
    # => arg1 is data.payload, arg2 is data.status, arg3 is the additional object
service.get().error (err) ->
    # => err

होना ->चाहिए =>?
शेरलहोमन

1
@SherylHohman 2015 के दिनों में वापस यह कॉफीस्क्रिप्ट ( coffeescript.org/#introduction ) के साथ लिखा गया था न कि ES6 सिंटेक्स। साधारण तीर सरल कार्य था और वसा तीर ES6 के रूप में लगभग समान हैं (मुझे लगता है कि ES6 वसा तीर CoffeScript से अधिक या कम उधार लिया गया है)।
वैल एंटिन

@SherylHohman यदि आप चाहें तो ECMA में पोस्ट को संपादित करने के लिए स्वतंत्र महसूस करें।
वैल एन्टिन

आपके प्रतिक्रिया के लिए धन्येवाद। मैं केवल यह स्पष्ट करने के लिए संपादन करूंगा कि यह एक कॉफी स्क्रिप्ट समाधान है। इसके साथ, आपका जवाब जैसा है वैसा ही है और CoffeeScript कोड बेस के लिए उपयोगी हो सकता है। हालाँकि, संपादित करने के लिए आपके प्रस्ताव के लिए धन्यवाद, 1) मैं कॉफीस्क्रिप्ट से संपादन / आपके समाधान को तोड़ने; 2) अपने कोड को आधुनिक जेएस में अनुवाद करना "अपने उत्तर के मूल इरादे" से विचलन माना जाना चाहिए, इस प्रकार एक 'संपादन' की समीक्षा को पारित नहीं करना चाहिए। बल्कि, कोई व्यक्ति एक नया उत्तर पोस्ट कर सकता है, यदि ऐसा है तो आपके कोड का अनुवाद कर सकता है। आदर्श रूप से, वे आपके उत्तर को अपनी प्रेरणा के रूप में वापस जोड़ लेंगे :-)
शेरिलहोमैन

0

महान सवाल, और बेंजामिन, क्रिस, एट अल द्वारा महान जवाब - बहुत धन्यवाद!

मैं इसे एक परियोजना में उपयोग कर रहा हूं और बेंजामिन ग्रुएनवाल्ड के कोड के आधार पर एक मॉड्यूल बनाया है । यह npmjs पर उपलब्ध है:

npm i -S promise-spread

फिर अपने कोड में, करें

require('promise-spread');

यदि आप एक पुस्तकालय का उपयोग कर रहे हैं जैसे any-promise

var Promise = require('any-promise');
require('promise-spread')(Promise);

शायद दूसरों को भी यह उपयोगी लगता है!


0

ईएस 6 में डी-स्ट्रक्चरिंग असाइनमेंट यहां मदद करेगा। इसके लिए:

let [arg1, arg2] = new Promise((resolve, reject) => {
    resolve([argument1, argument2]);
});

0

चूंकि जावास्क्रिप्ट में कार्यों को किसी भी तर्क के साथ बुलाया जा सकता है, और दस्तावेज़ onFulfilled()नीचे दिए गए खंड के अलावा विधि के तर्कों पर कोई प्रतिबंध नहीं लगाता है , मुझे लगता है कि आप onFulfilled()विधि के लिए कई तर्क पास कर सकते हैं जब तक कि वादा का मूल्य है पहला तर्क।

२.२.२.१ यह वादा पूरा होने के बाद कहा जाना चाहिए, वादा के मूल्य के साथ इसका पहला तर्क।


-1

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

मैं आमतौर पर किसी भी मूल वादा सवालों के लिए इस पृष्ठ को देखता हूं, मुझे बताएं कि क्या मैं गलत हूं

http://www.html5rocks.com/en/tutorials/es6/promises/


1
यह गलत है, new Promiseवाक्यविन्यास है function(resolve, error)जबकि thenवाक्यविन्यास है.then(function(arg) {
मेगावेक

2
@megawac यह वास्तव में केवल बुरी तरह से सही है - फिर दो (कभी-कभी 3) तर्क स्वीकार करता है - यह सिर्फ असामान्य है
बेंजामिन ग्रुएनबाउम

@BenjaminGruenbaum ने इसकी .then(function(/*resolve args*/){/*resolve handler*/}, function(/*reject args*/){/*reject handler*/})
शुरुआत की

2
हां, यदि आप बारीकी से पढ़ते हैं, तो यही उत्तर दावा कर रहा है - इस प्रश्न के संदर्भ में बहुत उपयोगी नहीं है लेकिन गलत नहीं है।
बेंजामिन ग्रुएनबाम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.