वादा करता है, फिर अतिरिक्त मापदंडों को चेन से गुजारें


100

एक वादा, उदाहरण के लिए:

var P = new Promise(function (resolve, reject) {
  var a = 5;
  if (a) {
    setTimeout(function(){
      resolve(a);
    }, 3000);
  } else {
    reject(a);
  }
});

हम कॉल करते हैं, तो वादे पर विधि:

P.then(doWork('text'));

doWork फ़ंक्शन इस तरह दिखता है:

function doWork(data) {
  return function(text) {
    // sample function to console log
    consoleToLog(data);
    consoleToLog(b);
  }
}

वादे और पाठ मापदंडों से डेटा तक पहुंच प्राप्त करने के लिए, मैं doWork में एक आंतरिक फ़ंक्शन को वापस करने से कैसे बच सकता हूं? क्या आंतरिक कार्य से बचने के लिए कोई चाल है?


1
कोई जानबूझकर करीने का त्याग क्यों करेगा ? गुप्त bindविधि का उपयोग करने के लिए ? - जो बेहद धीमा भी है।

@ मैं आपको समझ नहीं पा रहा हूँ, क्या आप कृपया स्पष्टीकरण के लिए कुछ कोड प्रदान कर सकते हैं?
रोलैंड

जवाबों:


86

आप Function.prototype.bindइस तरह के पहले तर्क के लिए पारित मूल्य के साथ एक नया फ़ंक्शन बनाने के लिए उपयोग कर सकते हैं

P.then(doWork.bind(null, 'text'))

और आप इसे बदल सकते हैं doWork,

function doWork(text, data) {
  consoleToLog(data);
}

अब, textवास्तव 'text'में होगा doWorkऔर dataवादा द्वारा हल किया गया मूल्य होगा।

नोट: कृपया सुनिश्चित करें कि आप अपने वादे की श्रृंखला में अस्वीकृति हैंडलर संलग्न करें।


कार्य कार्यक्रम: बैबिल की REPL पर लाइव कॉपी

function doWork(text, data) {
  console.log(text + data + text);
}

new Promise(function (resolve, reject) {
    var a = 5;
    if (a) {
      setTimeout(function () {
        resolve(a);
      }, 3000);
    } else {
      reject(a);
    }
  })
  .then(doWork.bind(null, 'text'))
  .catch(console.error);

धन्यवाद, कि मदद करता है, पहले मैं doWork.call की कोशिश करता हूं (यह, 'पाठ'), लेकिन डेटा को 'पाठ' द्वारा बदल दिया गया था
user3110667

2
callएक समारोह में जगह bindबनाता है, एक नया फ़ंक्शन बनाता है, हालांकि दोनों एक निष्पादन संदर्भ को अपने पहले तर्क के रूप में स्वीकार करते हैं।
sdgluck

103

शायद सबसे सीधा जवाब है:

P.then(function(data) { return doWork('text', data); });

या, चूंकि यह ecmascript-6तीर कार्यों का उपयोग करके टैग किया गया है:

P.then(data => doWork('text', data));

मुझे यह सबसे अधिक पठनीय लगता है, और लिखने के लिए बहुत ज्यादा नहीं।


5

करी का प्रयोग करें।

var P = new Promise(function (resolve, reject) {
    var a = 5;
    if (a) {
        setTimeout(function(){
            resolve(a);
        }, 3000);
    } else {
        reject(a);
    }
});

var curriedDoWork = function(text) {
    return function(data) {
        console.log(data + text);
    }
};

P.then(curriedDoWork('text'))
.catch(
    //some error handling
);

इस से सावधान रहें, यदि आप इस फ़ंक्शन की पहली पंक्ति पर curriedDoWorkएक वादा करते हैं , तो return new Promise()जैसे ही आप कॉल करते हैं, वादे को निष्पादित किया जाता है curriedDoWork()(जैसे आप करते हैं..then(curriedDoWork('text'))
फ्लेम

@ नाम: संक्षिप्त उत्तर, अपनी सुविधा के लिए, यदि आप ऐसा करना चाहते हैं, तो आप एक फ़ंक्शन में वादे को लपेट सकते हैं।
जर्मेन

@ आप, इस वाक्यविन्यास को इंगित कर सकते हैं जो कि काफी दिलचस्प है curriedWork = पाठ => डेटा => कंसोल.लॉग (डेटा + पाठ)
जर्मनी

1
@germain आह हाँ, मैंने यह रूप पहले देखा है, कार्यात्मक प्रोग्रामिंग से प्यार होगा। हालाँकि, मुझे लगता है कि कुछ ब्राउज़र में एरो फ़ंक्शंस टूट जाते हैं, इसलिए मैं अब इससे बचना चाहता हूँ।
यक्ष

@ ऑक्स, केवल इंटरनेट एक्सप्लोरर इसका समर्थन नहीं करता है और एज के कारण कभी भी नहीं होगा, इंटरनेट एक्सप्लोरर आखिरी बिल्ड 9 दिसंबर 2015 था। चलो ~
जर्मनी

0

लॉडश इस सटीक चीज़ के लिए एक अच्छा विकल्प प्रदान करता है।

 P.then(_.bind(doWork, 'myArgString', _));

 //Say the promise was fulfilled with the string 'promiseResults'

 function doWork(text, data) {
     console.log(text + " foo " + data);
     //myArgString foo promiseResults
 }

या, यदि आप अपने सफलता समारोह को केवल एक पैरामीटर (पूर्ण किए गए वादे के अनुसार) करना चाहते हैं, तो आप इसे इस तरह से उपयोग कर सकते हैं:

P.then(_.bind(doWork, {text: 'myArgString'}));

function doWork(data) {
    console.log(data + " foo " + this.text);
    //promiseResults foo myArgString
}

यह फ़ंक्शन text: 'myArgString'के thisसंदर्भ में संलग्न होगा ।


0

इस प्रश्न का नया उत्तर है, एरो फ़ंक्शंस का उपयोग करना, जो स्वचालित रूप से 'इस' को बांधता है और बहुत अधिक पठनीय है। Google जैसे लिंक के लिए: https://2ality.com/2016/02/arrow-functions-vs-bind.html

आप पाठ सेट कर सकते हैं जैसे: this.text = 'text' P.then (data => doWork (data)); //this.text doWork के अंदर 'टेक्स्ट' का मूल्यांकन करेगा।

यह ऊपर जिब द्वारा सुझाया गया है और वह (या यह!) अब स्वीकृत उत्तर होना चाहिए।

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