फ़ंक्शन के दायरे से बाहर जावास्क्रिप्ट का वादा करें


279

मैं ES6 प्रॉमिस का उपयोग कर रहा हूं।

आमतौर पर, एक वादा इस तरह का निर्माण और उपयोग किया जाता है

new Promise(function(resolve, reject){
    if (someCondition){
        resolve();
    } else {
        reject();
    } 
});

लेकिन मैं लचीलेपन के लिए बाहर संकल्प लेने के लिए नीचे जैसा कुछ कर रहा हूं।

var outsideResolve;
var outsideReject;
new Promise(function(resolve, reject) { 
    outsideResolve = resolve; 
    outsideReject = reject; 
});

और बादमें

onClick = function(){
    outsideResolve();
}

यह ठीक काम करता है, लेकिन क्या ऐसा करने का एक आसान तरीका है? यदि नहीं, तो क्या यह अच्छा अभ्यास है?


2
मुझे नहीं लगता कि कोई दूसरा तरीका है। मेरा मानना ​​है कि यह निर्दिष्ट है कि कॉलबैक Promiseको दो कार्यों को "निर्यात" करने की अनुमति देने के लिए समान रूप से निष्पादित किया जाना है।
फेलिक्स क्लिंग

1
यह मेरे लिए ठीक वैसे ही काम करता है जैसे आपने लिखा था। जहां तक ​​मेरा सवाल है, यह "विहित" तरीका है।
गिलाद बार्नर

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

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

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

जवाबों:


93

नहीं, ऐसा करने का कोई और तरीका नहीं है - केवल एक चीज मैं कह सकता हूं कि यह उपयोग मामला बहुत सामान्य नहीं है। जैसे फेलिक्स ने टिप्पणी में कहा - आप जो करते हैं वह लगातार काम करेगा।

यह ध्यान देने योग्य है कि वादे का निर्माण करने वाला इस तरह से व्यवहार करता है, यह सुरक्षा फेंकना है - यदि आप अपवाद का अनुमान नहीं लगाते हैं, जबकि आपका कोड वादा निर्माता के अंदर चल रहा है तो यह अस्वीकृति में बदल जाएगा, फेंक सुरक्षा का यह रूप - फेंक दिया त्रुटियों को परिवर्तित करना अस्वीकृति महत्वपूर्ण है और पूर्वानुमान कोड बनाए रखने में मदद करती है।

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

var p = new Promise(function(resolve, reject){
    this.onclick = resolve;
}.bind(this));

इस कारण से - जब भी आप फ़ंक्शंस के निर्यात पर वादे करने वाले कंस्ट्रक्टर का उपयोग कर सकते हैं - मेरा सुझाव है कि आप इसका उपयोग करें। जब भी आप दोनों से बच सकते हैं - दोनों और श्रृंखला से बचें।

ध्यान दें, आपको कभी भी चीजों के लिए वादे के निर्माणकर्ता का उपयोग नहीं करना चाहिए if(condition), पहला उदाहरण इस प्रकार लिखा जा सकता है:

var p = Promise[(someCondition)?"resolve":"reject"]();

2
हाय बेंजामिन! क्या वर्तमान में स्वादिष्ट वायदा चीनी प्राप्त करने का कोई बेहतर तरीका नहीं है अगर हम नहीं जानते कि वादा कब पूरा होगा? अतुल्यकालिक प्रतीक्षा / सूचना पैटर्न के कुछ प्रकार की तरह ? उदाहरण के लिए, "स्टोर", और बाद में एक Promiseश्रृंखला शुरू करें? जैसे मेरे विशेष मामले में, मैं एक सर्वर पर हूं, जो एक विशिष्ट ग्राहक उत्तर (SYN-ACK-kinda हैंड-शेक के लिए प्रतीक्षा कर रहा है ताकि यह सुनिश्चित हो सके कि क्लाइंट सफलतापूर्वक अपडेट की गई अवस्था में है)।
डोमी

1
@Domi क्यू-कनेक्शन और RxJS की जाँच करें।
बेंजामिन ग्रुएनबाम 14

2
मैं एक ही एपीआई एपीआई का उपयोग कैसे कर सकता हूं?
विनोद सोबेल

95
आम नहीं? मैं लगभग हर परियोजना की जरूरत है।
टॉम ज़ातो -

1
Usecase पर विचार करने के लिए आपको एक घटना के ट्रिगर होने के बाद कुछ और करने की आवश्यकता है और कुछ और हुआ। आप एक वादे में घटना को बदलना चाहते हैं और इसे एक और वादा के साथ एकजुट करते हैं। मेरे लिए एक सामान्य समस्या की तरह लगता है।
घुमारवीं

130

सरल:

var promiseResolve, promiseReject;

var promise = new Promise(function(resolve, reject){
  promiseResolve = resolve;
  promiseReject = reject;
});

promiseResolve();

2
@ruX, जैसा कि स्वीकृत उत्तर में उल्लेख किया गया है - इसे इस तरह से डिजाइन किया गया था। मुद्दा यह है कि यदि एक अपवाद को फेंक दिया जाता है, तो यह वादा निर्माता द्वारा पकड़ा जाएगा। इस उत्तर (साथ ही मेरा) में जो भी कोड कॉल के लिए एक अपवाद फेंकने की संभावना है promiseResolve()। एक वादा के शब्दार्थ यह है कि यह हमेशा एक मूल्य देता है। यह भी कार्यात्मक रूप से ओपी के पद के समान है, मुझे यह समस्या नहीं आती है कि यह पुन: प्रयोज्य तरीके से क्या हल कर रहा है।
जॉन जैक्स

4
@JonJaques मुझे यकीन नहीं है कि आप जो कहते हैं वह सच है। कोड जो कॉल करता है promiseResolve()वह अपवाद नहीं फेंकेगा। आप .catchकंस्ट्रक्टर पर परिभाषित कर सकते हैं और कोई फर्क नहीं पड़ता कि क्या कोड इसे कॉल करता है, कंस्ट्रक्टर .catchको बुलाया जाएगा। यहाँ jsbin प्रदर्शित करता है कि यह कैसे काम करता है: jsbin.com/yicerewivo/edit?js,console
carter

हाँ, यह पकड़ा गया है क्योंकि आपने इसके चारों ओर एक और वादा निर्माता को लपेट दिया है - बिल्कुल वही बिंदु जो मैं बनाने की कोशिश कर रहा हूं। हालाँकि, आपको कुछ अन्य कोड बताए
जॉन जैक्स

8
मुझे यकीन भी नहीं है कि यह एक बुरा डिज़ाइन है। वादे से बाहर की गई एक त्रुटि को वादे के भीतर पकड़ा नहीं जाना चाहिए। यह शायद गलत धारणा या बुरी समझ का एक उदाहरण है, अगर डिजाइनर वास्तव में त्रुटि को पकड़े जाने की उम्मीद करता है।
काल ईल

3
यह सटीक निर्माण पहले से ही प्रश्न में उल्लिखित है। क्या आपने भी इसे पढ़ा?
सेड्रिक रीचेनबाक

103

यहां पार्टी के लिए थोड़ा देर से, लेकिन इसे करने का एक और तरीका एक आस्थगित वस्तु का उपयोग करना होगा । आपके पास अनिवार्य रूप से बॉयलरप्लेट की समान मात्रा है, लेकिन यह आसान है अगर आप उन्हें चारों ओर से गुजरना चाहते हैं और संभवतः उनकी परिभाषा के बाहर हल करते हैं।

Naive कार्यान्वयन:

class Deferred {
  constructor() {
    this.promise = new Promise((resolve, reject)=> {
      this.reject = reject
      this.resolve = resolve
    })
  }
}

function asyncAction() {
  var dfd = new Deferred()

  setTimeout(()=> {
    dfd.resolve(42)
  }, 500)

  return dfd.promise
}

asyncAction().then(result => {
  console.log(result) // 42
})

ES5 संस्करण:

function Deferred() {
  var self = this;
  this.promise = new Promise(function(resolve, reject) {
    self.reject = reject
    self.resolve = resolve
  })
}

function asyncAction() {
  var dfd = new Deferred()

  setTimeout(function() {
    dfd.resolve(42)
  }, 500)

  return dfd.promise
}

asyncAction().then(function(result) {
  console.log(result) // 42
})

1
लेक्सिकल स्कूपिंग पर ध्यान दें।
फ्लोर्री

1
इस बात का कोई व्यावहारिक अंतर नहीं है कि क्या resolve|rejectlexically या इसके माध्यम से असाइन किया गया है bind। यह सिर्फ jQuery के आस्थगित ऑब्जेक्ट का एक सरल कार्यान्वयन है जो लगभग 1.0 (ईश) के बाद से है। यह बिलकुल वादे की तरह काम करता है, सिवाय इसके कि कोई सुरक्षा नहीं है। इस प्रश्न का संपूर्ण बिंदु यह था कि वादे करते समय कोड की कुछ पंक्तियों को कैसे बचाया जाए।
जॉन जैक्स

1
एक आस्थगित का उपयोग करना ऐसा करने का सामान्य तरीका है, मुझे नहीं पता कि यह अधिक क्यों नहीं है
ब्लूराजा - डैनी पफ्लुगुएफ्ट

1
बहुत बढ़िया जवाब! JQuery प्रदान करता है कि स्थगित कार्यक्षमता के लिए देख रहा था।
अंशुल कोका

2
है Deferredपदावनत?
पचेरियर

19

एक समाधान मैं 2015 में अपने ढांचे के लिए आया था। मैंने इस प्रकार के वादों को टास्क कहा

function createPromise(handler){
  var _resolve, _reject;

  var promise = new Promise(function(resolve, reject){
    _resolve = resolve; 
    _reject = reject;

    handler(resolve, reject);
  })

  promise.resolve = _resolve;
  promise.reject = _reject;

  return promise;
}

var promise = createPromise()
promise.then(function(data){ alert(data) })

promise.resolve(200) // resolve from outside

4
धन्यवाद, यह काम किया। लेकिन हैंडलर क्या है? मुझे इसे काम करने के लिए हटाना पड़ा।
शहीद

16

मुझे @JonJaques उत्तर पसंद आया लेकिन मैं इसे एक कदम आगे ले जाना चाहता था।

यदि आप ऑब्जेक्ट को बाँधते हैं thenऔर catchफिर उसे Deferredहटाते हैं, तो यह पूरी तरह से Promiseएपीआई को लागू करता है और आप इसे वादे के रूप में मान सकते awaitहैं।

class DeferredPromise {
  constructor() {
    this._promise = new Promise((resolve, reject) => {
      // assign the resolve and reject functions to `this`
      // making them usable on the class instance
      this.resolve = resolve;
      this.reject = reject;
    });
    // bind `then` and `catch` to implement the same interface as Promise
    this.then = this._promise.then.bind(this._promise);
    this.catch = this._promise.catch.bind(this._promise);
    this[Symbol.toStringTag] = 'Promise';
  }
}

const deferred = new DeferredPromise();
console.log('waiting 2 seconds...');
setTimeout(() => {
  deferred.resolve('whoa!');
}, 2000);

async function someAsyncFunction() {
  const value = await deferred;
  console.log(value);
}

someAsyncFunction();


10

एक सहायक विधि इस अतिरिक्त उपरि को समाप्त कर देगी, और आपको वही jQuery का अनुभव देगी।

function Deferred() {
    let resolve;
    let reject;
    const promise = new Promise((res, rej) => {
        resolve = res;
        reject = rej;
    });
    return { promise, resolve, reject };
}

उपयोग होगा

const { promise, resolve, reject } = Deferred();
displayConfirmationDialog({
    confirm: resolve,
    cancel: reject
});
return promise;

जो jQuery के समान है

const dfd = $.Deferred();
displayConfirmationDialog({
    confirm: dfd.resolve,
    cancel: dfd.reject
});
return dfd.promise();

हालांकि, एक उपयोग के मामले में यह सरल, देशी वाक्यविन्यास ठीक है

return new Promise((resolve, reject) => {
    displayConfirmationDialog({
        confirm: resolve,
        cancel: reject
    });
});

8

मैं एक सहायक फ़ंक्शन का उपयोग कर रहा हूं, जिसे मैं "फ्लैट वादा" कहता हूं -

function flatPromise() {

    let resolve, reject;

    const promise = new Promise((res, rej) => {
      resolve = res;
      reject = rej;
    });

    return { promise, resolve, reject };
}

और मैं इसे इस तरह उपयोग कर रहा हूँ -

function doSomethingAsync() {

    // Get your promise and callbacks
    const { resolve, reject, promise } = flatPromise();

    // Do something amazing...
    setTimeout(() => {
        resolve('done!');
    }, 500);

    // Pass your promise to the world
    return promise;

}

पूर्ण कार्य उदाहरण देखें -

संपादित करें: मैंने एक एनपीएम पैकेज बनाया है जिसे फ्लैट-वादा कहा जाता है और कोड गीथहब पर भी उपलब्ध है


7

आप एक वर्ग में प्रोमिस को लपेट सकते हैं।

class Deferred {
    constructor(handler) {
        this.promise = new Promise((resolve, reject) => {
            this.reject = reject;
            this.resolve = resolve;
            handler(resolve, reject);
        });

        this.promise.resolve = this.resolve;
        this.promise.reject = this.reject;

        return this.promise;
    }
    promise;
    resolve;
    reject;
}

// How to use.
const promise = new Deferred((resolve, reject) => {
  // Use like normal Promise.
});

promise.resolve(); // Resolve from any context.

6

यहाँ कई उत्तर इस लेख के अंतिम उदाहरण के समान हैं । मैं कई वादे कैशिंग रहा हूँ, और resolve()और reject()कार्यों में किसी भी चर या संपत्ति को सौंपा जा सकता। परिणामस्वरूप मैं इस कोड को थोड़ा और अधिक कॉम्पैक्ट बनाने में सक्षम हूं:

function defer(obj) {
    obj.promise = new Promise((resolve, reject) => {
        obj.resolve = resolve;
        obj.reject  = reject;
    });
}

इस संस्करण का उपयोग करने का एक सरलीकृत उदाहरण defer()एक FontFaceअन्य एसिंक्स प्रक्रिया के साथ एक लोड वादा को संयोजित करने के लिए है :

function onDOMContentLoaded(evt) {
    let all = []; // array of Promises
    glob = {};    // global object used elsewhere
    defer(glob);
    all.push(glob.promise);
    // launch async process with callback = resolveGlob()

    const myFont = new FontFace("myFont", "url(myFont.woff2)");
    document.fonts.add(myFont);
    myFont.load();
    all.push[myFont];
    Promise.all(all).then(() => { runIt(); }, (v) => { alert(v); });
}
//...
function resolveGlob() {
    glob.resolve();
}
function runIt() {} // runs after all promises resolved 

अद्यतन: यदि आप ऑब्जेक्ट को एनकैप्सुलेट करना चाहते हैं तो 2 विकल्प:

function defer(obj = {}) {
    obj.promise = new Promise((resolve, reject) => {
        obj.resolve = resolve;
        obj.reject  = reject;
    });
    return obj;
}
let deferred = defer();

तथा

class Deferred {
    constructor() {
        this.promise = new Promise((resolve, reject) => {
            this.resolve = resolve;
            this.reject  = reject;
        });
    }
}
let deferred = new Deferred();

यदि आप इन उदाहरणों का उपयोग एक async फ़ंक्शन में कर रहे हैं, तो आपको वादे की संपत्ति का उल्लेख करना होगा, जब आप हल किए गए वादे के मूल्य का उपयोग करना चाहते हैं:const result = await deferred.promise;
b00t

6

स्वीकृत उत्तर गलत है। यह बहुत आसान गुंजाइश और संदर्भ उपयोग कर रहा है, हालांकि यह कर सकते हैं वादा शुद्धतावादियों गुस्सा:

const createPromise = () => {
    let resolver;
    return [
        new Promise((resolve, reject) => {
            resolver = resolve;
        }),
        resolver,
    ];
};

const [ promise, resolver ] = createPromise();
promise.then(value => console.log(value));
setTimeout(() => resolver('foo'), 1000);

हम मूल रूप से संकल्प समारोह के संदर्भ को पकड़ रहे हैं जब वादा किया जाता है, और हम वापस लौटते हैं ताकि इसे बाहरी रूप से सेट किया जा सके।

एक सेकंड में कंसोल आउटपुट देगा:

> foo

मुझे लगता है कि यह सबसे अच्छा तरीका है। केवल एक चीज यह है कि कोड थोड़ा कम क्रिया हो सकता है।
पीआई

अच्छा! चतुर विचार। +50 अगर मैं कर सका।
Mitya

बस यही ओपी ने किया। वास्तव में आप वादों पर आस्थगित पैटर्न का फिर से आविष्कार कर रहे हैं, बेशक यह संभव है और आपका दृष्टिकोण (प्रारंभिक ओपी कोड के रूप में) काम करता है, लेकिन स्वीकृत उत्तर में वर्णित "थ्रो सेफ्टी कारण" के कारण यह सर्वोत्तम अभ्यास नहीं है।
dhilt

4

हाँ तुम कर सकते हो। CustomEventब्राउज़र वातावरण के लिए एपीआई का उपयोग करके । और नोड में एक घटना emitter परियोजना का उपयोग कर। Js वातावरण। चूंकि प्रश्न में स्निपेट ब्राउज़र वातावरण के लिए है, इसलिए यहां उसी के लिए एक कार्यशील उदाहरण है।

function myPromiseReturningFunction(){
  return new Promise(resolve => {
    window.addEventListener("myCustomEvent", (event) => {
       resolve(event.detail);
    }) 
  })
}


myPromiseReturningFunction().then(result => {
   alert(result)
})

document.getElementById("p").addEventListener("click", () => {
   window.dispatchEvent(new CustomEvent("myCustomEvent", {detail : "It works!"}))
})
<p id="p"> Click me </p>

मुझे आशा है कि यह उत्तर उपयोगी है!


3

हमारा समाधान संकल्पों को अस्वीकार करने / कार्यों को स्टोर करने के लिए क्लोजर का उपयोग करना था और इसके अलावा खुद को वादा करने के लिए एक फ़ंक्शन संलग्न करना था।

यहाँ पैटर्न है:

function getPromise() {

    var _resolve, _reject;

    var promise = new Promise((resolve, reject) => {
        _reject = reject;
        _resolve = resolve;
    });

    promise.resolve_ex = (value) => {
       _resolve(value);
    };

    promise.reject_ex = (value) => {
       _reject(value);
    };

    return promise;
}

और इसका उपयोग करते हुए:

var promise = getPromise();

promise.then(value => {
    console.info('The promise has been fulfilled: ' + value);
});

promise.resolve_ex('hello');  
// or the reject version 
//promise.reject_ex('goodbye');

2
महान ... मैं सिर्फ वादे सीख रहा हूं, लेकिन इस तथ्य से लगातार हैरान हूं कि आप उन्हें "कहीं और" हल करने में सक्षम नहीं दिखते हैं। कार्यान्वयन विवरण छिपाने के लिए एक बंद का उपयोग करना एक महान विचार है ... लेकिन वास्तव में मुझे यकीन नहीं है कि आपने क्या किया है: इसके बजाय "छद्म" निजी चर हैं मुझे पूरा यकीन है कि चर को पूरी तरह से छिपाने का एक तरीका है जो दुर्गम होना चाहिए ... जो वास्तव में बंद करने का मतलब है ...
माइक

> एक कोड कोड का एक खंड है जिसे संदर्भित किया जा सकता है (और चारों ओर पारित किया गया है) जो एन्क्लेविंग दायरे के चर तक पहुंच के साथ है। var _resolve, _reject; घेरने की गुंजाइश है।
स्टीवन स्पंगिन

हाँ, पर्याप्त निष्पक्ष। वास्तव में यह मुझे लगता है कि मेरा उत्तर चीजों को ओवरकम्प्लीकेट कर रहा है, और इसके अलावा आपका उत्तर सरल हो सकता है: आपको बस जाने की जरूरत है promise.resolve_ex = _resolve; promise.reject_ex = _reject;... फिर भी ठीक काम करता है।
माइक

" वादा निभाने के लिए एक समारोह संलग्न करें। " - ऐसा मत करो। वादे परिणाम मान हैं, उन्हें हल करने की क्षमता प्रदान नहीं करनी चाहिए। आप उन विस्तारित लोगों को पास नहीं करना चाहते हैं।
बेर्गी

2
सवाल यह था कि इसे दायरे से बाहर कैसे हल किया जाए। यहां एक समाधान है जो काम करता है, और हमारे उत्पादन में हमारे पास वास्तव में इसे करने का एक आवश्यक कारण है। मैं यह नहीं देखता कि क्यों बताई गई समस्या को हल करना एक नीचता है।
स्टीवन स्पूंगिन

2

मैं खुद को डिफर्ड पैटर्न के साथ-साथ कुछ मामलों में याद कर रहा हूं। आप हमेशा ES6 वादा के शीर्ष पर एक बना सकते हैं:

export default class Deferred<T> {
    private _resolve: (value: T) => void = () => {};
    private _reject: (value: T) => void = () => {};

    private _promise: Promise<T> = new Promise<T>((resolve, reject) => {
        this._reject = reject;
        this._resolve = resolve;
    })

    public get promise(): Promise<T> {
        return this._promise;
    }

    public resolve(value: T) {
        this._resolve(value);
    }

    public reject(value: T) {
        this._reject(value);
    }
}

2

इस धागे में पोस्ट करने वाले सभी को धन्यवाद। मैंने एक मॉड्यूल बनाया जिसमें पहले वर्णित डेफर () ऑब्जेक्ट और साथ ही उस पर निर्मित कुछ अन्य ऑब्जेक्ट शामिल हैं। वे सभी एक कार्यक्रम के भीतर संचार / घटना से निपटने के कार्यान्वयन के लिए वादा और साफ वादा कॉल-बैक सिंटैक्स का लाभ उठाते हैं।

  • Defer: वादा किया गया है जिसे दूर से विफल किया जा सकता है (इसके शरीर के बाहर)
  • विलंब: वह वादा जो किसी निश्चित समय के बाद स्वतः हल हो जाता है
  • टाइमऑट: वादा जो एक निश्चित समय के बाद स्वचालित रूप से विफल हो जाता है।
  • साइकिल: वादा सिंटैक्स के साथ घटनाओं को प्रबंधित करने के लिए पुन: ट्रिगर करने योग्य वादा
  • कतार: प्रोमिस चाइनिंग पर आधारित निष्पादन कतार।

    rp = require("repeatable-promise")

    https://github.com/CABrouwers/repeatable-promise


1

मैंने इसके लिए एक छोटा सा दायित्व लिखा। https://www.npmjs.com/package/@inf3rno/promise.exposed

मैं कारखाने विधि दृष्टिकोण दूसरों लिखा करते थे, लेकिन मैं overrode then, catch, finallyतरीकों भी है, तो आप अच्छी तरह से उन लोगों द्वारा मूल वादा हल कर सकते हैं।

बाहर से निष्पादक के बिना वादा हल करना:

const promise = Promise.exposed().then(console.log);
promise.resolve("This should show up in the console.");

बाहर से निष्पादक के सेटटाइमआउट के साथ रेसिंग:

const promise = Promise.exposed(function (resolve, reject){
    setTimeout(function (){
        resolve("I almost fell asleep.")
    }, 100000);
}).then(console.log);

setTimeout(function (){
    promise.resolve("I don't want to wait that much.");
}, 100);

यदि आप वैश्विक नाम स्थान को प्रदूषित नहीं करना चाहते हैं, तो कोई संघर्ष नहीं है:

const createExposedPromise = require("@inf3rno/promise.exposed/noConflict");
const promise = createExposedPromise().then(console.log);
promise.resolve("This should show up in the console.");

1

मैंने एक पुस्तकालय बनाया, जो manual-promiseप्रतिस्थापन के लिए एक बूंद के रूप में कार्य करता है Promise। अन्य उत्तरों में से कोई भी यहाँ के लिए प्रतिस्थापन में गिरावट के रूप में काम नहीं करेगा Promise, क्योंकि वे परदे के पीछे या आवरण का उपयोग करते हैं।

yarn add manual-promise

npn install manual-promise


import { ManualPromise } from "manual-promise";

const prom = new ManualPromise();

prom.resolve(2);

// actions can still be run inside the promise
const prom2 = new ManualPromise((resolve, reject) => {
    // ... code
});


new ManualPromise() instanceof Promise === true

https://github.com/zpxp/manual-promise#readme


0

कैसे एक समारोह बनाने के बारे में अस्वीकार अपहरण और इसे वापस करने के लिए?

function createRejectablePromise(handler) {
  let _reject;

  const promise = new Promise((resolve, reject) => {
    _reject = reject;

    handler(resolve, reject);
  })

  promise.reject = _reject;
  return promise;
}

// Usage
const { reject } = createRejectablePromise((resolve) => {
  setTimeout(() => {
    console.log('resolved')
    resolve();
  }, 2000)

});

reject();

0

मैंने एक साथ काम करने वाले एक जिस्ट को रखा है: https://gist.github.com/thiagoh/c24310b562d50a14f3e7602a82b4ef13

यहां आपको इसका उपयोग कैसे करना चाहिए:

import ExternalizedPromiseCreator from '../externalized-promise';

describe('ExternalizedPromise', () => {
  let fn: jest.Mock;
  let deferredFn: jest.Mock;
  let neverCalledFn: jest.Mock;
  beforeEach(() => {
    fn = jest.fn();
    deferredFn = jest.fn();
    neverCalledFn = jest.fn();
  });

  it('resolve should resolve the promise', done => {
    const externalizedPromise = ExternalizedPromiseCreator.create(() => fn());

    externalizedPromise
      .promise
      .then(() => deferredFn())
      .catch(() => neverCalledFn())
      .then(() => {
        expect(deferredFn).toHaveBeenCalled();
        expect(neverCalledFn).not.toHaveBeenCalled();
        done();
      });

    expect(fn).toHaveBeenCalled();
    expect(neverCalledFn).not.toHaveBeenCalled();
    expect(deferredFn).not.toHaveBeenCalled();

    externalizedPromise.resolve();
  });
  ...
});

0

पहले ब्राउज़र या नोड पर --allow-natives-syntax सक्षम करें

const p = new Promise(function(resolve, reject){
    if (someCondition){
        resolve();
    } else {
        reject();
    } 
});

onClick = function () {
    %ResolvePromise(p, value)
}

0

बाहर से वादा करने के लिए बस एक और समाधान

 class Lock {
        #lock;  // Promise to be resolved (on  release)
        release;  // Release lock
        id;  // Id of lock
        constructor(id) {
            this.id = id
            this.#lock = new Promise((resolve) => {
                this.release = () => {
                    if (resolve) {
                        resolve()
                    } else {
                        Promise.resolve()
                    }
                }
            })
        }
        get() { return this.#lock }
    }

प्रयोग

let lock = new Lock(... some id ...);
...
lock.get().then(()=>{console.log('resolved/released')})
lock.release()  // Excpected 'resolved/released'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.