জাভাস্ক্রিপ্ট প্রতিশ্রুতি ফাংশন সুযোগ বাইরে সমাধান করুন


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
আমি মনে করি ভবিষ্যতে এটি অর্জনের একটি আনুষ্ঠানিক উপায় থাকা উচিত। এই বৈশিষ্ট্যটি আমার মতে খুব শক্তিশালী কারণ আপনি অন্যান্য প্রসঙ্গ থেকে মানগুলির জন্য অপেক্ষা করতে পারেন।
জোসে

যখনই তারা এই সমস্যার যথাযথ সমাধান নিয়ে আসে, আমি আশা করি তারা এটিকে নেস্টেড প্রতিশ্রুতিগুলির জন্যও কাজ করবে, যার মধ্যে কিছু পুনরাবৃত্তি হতে পারে।
আর্থার তারাসভ

আমি মনে করি প্রতিশ্রুতি API এগুলি সর্বদা রিটার্ন মান হিসাবে ব্যবহার করার জন্য "পরামর্শ" দেয় এবং আপনি যে অ্যাক্সেস বা কল করতে পারেন এমন কোনও বস্তু হিসাবে কখনও তা ব্যবহার করবেন না। অন্য কথায় আমরা আমাদের যে অ্যাক্সেস করতে পারি বা যে ফাংশনগুলিতে আমরা কল করতে পারি বা আমরা কোনও ভেরিয়েবলের সাথে উল্লেখ করতে পারি বা একটি প্যারামিটার হিসাবে পাস করতে পারি তার মতো পরিবর্তনের জন্য তাদেরকে ফেরত মান হিসাবে বিবেচনা করতে বাধ্য করি। যদি আপনি প্রতিশ্রুতি অন্য কোনও বিষয় হিসাবে ব্যবহার শুরু করেন তবে আপনি সম্ভবত আপনার প্রশ্নের মতো বাইরে থেকেও এটিকে সমাধান করার প্রয়োজন শেষ করুন ... যা বলা হচ্ছে, আমিও মনে করি এটি করার একটি আনুষ্ঠানিক উপায় থাকা উচিত ... এবং ডিফার্ড আমার কাছে কেবল একটি কাজ বলে মনে হচ্ছে না।
ক্যান্সারবেরো

উত্তর:


93

না, এটি করার অন্য কোনও উপায় নেই - কেবলমাত্র আমি বলতে পারি যে এই ব্যবহারের ক্ষেত্রে খুব সাধারণ ঘটনা নেই। যেমন ফেলিক্স মন্তব্যে বলেছিলেন - আপনি যা করবেন তা ধারাবাহিকভাবে কাজ করবে।

এটি উল্লেখ করার মতো বিষয় যে প্রতিশ্রুতিবদ্ধ নির্মাণকারীটি এইভাবে আচরণ করে সেগুলি হ'ল নিরাপত্তা ছুঁড়ে ফেলা - যদি প্রতিশ্রুতিবদ্ধ কনস্ট্রাক্টরের অভ্যন্তরে আপনার কোডটি চলমান থাকে তখন আপনি যদি একটি অপ্রকাশের কথা অনুমান করেন নি তবে তা প্রত্যাখাত হয়ে যাবে, নিক্ষেপ সুরক্ষার এই রূপ - নিক্ষিপ্ত ত্রুটিগুলিতে রূপান্তরিত প্রত্যাখ্যান গুরুত্বপূর্ণ এবং অনুমানযোগ্য কোড বজায় রাখতে সহায়তা করে।

এই নিক্ষেপ সুরক্ষার কারণ হিসাবে, প্রতিশ্রুতিবদ্ধ নির্মাণকারীকে স্থগিত করা হয়েছে (যা একটি বিকল্প প্রতিশ্রুতি নির্মাণের উপায় যা আপনি যা করছেন তা মঞ্জুরি দেয়) - সেরা অভ্যাস হিসাবে - আমি উপাদানটি পাস করব এবং পরিবর্তে প্রতিশ্রুতি ব্যবহারকারীর ব্যবহার করব:

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

এই কারণে - যখনই আপনি ফাংশন রফতানির উপর প্রতিশ্রুতিবদ্ধ নির্মাণকারীর ব্যবহার করতে পারেন - আমি আপনাকে এটি ব্যবহার করার পরামর্শ দিই। যখনই আপনি উভয় এড়াতে পারেন - উভয় এবং চেইন এড়ানো।

দ্রষ্টব্য, আপনার প্রতিশ্রুতিবদ্ধ নির্মাণকারীর মতো জিনিসগুলির জন্য কখনই ব্যবহার করা উচিত নয় if(condition), প্রথম উদাহরণটি এইভাবে লেখা যেতে পারে:

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

2
হাই বেনিয়ামিন! মুখের প্রতিশ্রুতি চিনি পাওয়ার আরও ভাল কোনও উপায় কি যদি আমরা জানি না যে প্রতিশ্রুতিটি এখনও পূরণ হবে? কিছু ধরণের অ্যাসিনক্রোনাস ওয়েট / নোটিফ প্যাটার্নের মতো ? উদাহরণস্বরূপ, "স্টোর" পছন্দ করুন, এবং পরে কোনও Promiseশৃঙ্খলা শুরু করবেন? উদাহরণস্বরূপ, আমার নির্দিষ্ট ক্ষেত্রে, আমি একটি সার্ভারে আছি, নির্দিষ্ট ক্লায়েন্টের জবাবের জন্য অপেক্ষা করছি (ক্লায়েন্টটি সফলভাবে আপডেট হওয়া রাষ্ট্রটি নিশ্চিত করার জন্য একটি এসওয়াইএন-এসি-কিন্ডা হ্যান্ড শেক)।
ডোমি 13

1
@ ডোমি কিউ-সংযোগ এবং আরএক্সজেএস পরীক্ষা করে দেখুন।
বেনজামিন গ্রুইনবাউম

2
ফেচ এপিআই ব্যবহার করে আমি কীভাবে একই কাজ করতে পারি?
বিনোদ সোবালে

95
সাধারন না? আমি প্রায় প্রতিটি প্রকল্পের প্রয়োজন শেষ।
টোমা জ্যাটো - মনিকা

1
ইউজকেস বিবেচনা করুন কোনও ইভেন্ট ট্রিগার হওয়ার পরে এবং অন্য কিছু ঘটনার পরে আপনার কিছু করা দরকার। আপনি ইভেন্টকে প্রতিশ্রুতিতে রূপান্তর করতে এবং এটি অন্য প্রতিশ্রুতি দিয়ে unক্যবদ্ধ করতে চান। আমার কাছে জেনেরিক সমস্যা মনে হচ্ছে।
ঘেরম্যান 8

130

সহজ:

var promiseResolve, promiseReject;

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

promiseResolve();

2
@ আরএক্স, যেমন গৃহীত উত্তরের উল্লেখ রয়েছে - এটি উদ্দেশ্যটির জন্য এইভাবে নকশা করা হয়েছিল। মুল বক্তব্যটি হ'ল যদি কোনও ব্যতিক্রম নিক্ষেপ করা হয় তবে এটি প্রতিশ্রুতিবদ্ধ নির্মাণকারীর দ্বারা ধরা পড়বে। এই উত্তরটির (পাশাপাশি আমার) কোড কোডগুলির জন্য সম্ভবত একটি ব্যতিক্রম ছুঁড়ে ফেলার সম্ভাবনা রয়েছে promiseResolve()। প্রতিশ্রুতির শব্দার্থকতা হ'ল এটি সর্বদা একটি মান দেয়। এছাড়াও এটি কার্যত অপার পোস্টের মতোই, এটি পুনরায় ব্যবহারযোগ্য উপায়ে কী সমস্যার সমাধান করছে তা আমি পাই না।
জোন জাকস

4
@ জোনজাক্স আমি নিশ্চিত নই যে আপনি যা বলেছেন তা সত্য কিনা। যে কোডগুলি কল করে সেগুলি promiseResolve()ব্যতিক্রম ছুঁড়ে ফেলবে না। আপনি .catchকনস্ট্রাক্টরের উপর একটি সংজ্ঞা দিতে পারেন এবং কোড যাই বলুক না কেন, কনস্ট্রাক্টরকে .catchডাকা হবে। এটি কীভাবে কাজ করে তা এখানে জেসবিন প্রদর্শন করছে: jsbin.com/yicerewivo/edit?js,console
carter

হ্যাঁ, এটি ধরা পড়েছে কারণ আপনি তার চারপাশে আরও একটি প্রতিশ্রুতি প্রদানকারীকে জড়িয়ে দিয়েছিলেন - ঠিক আমি যে পয়েন্টটি করার চেষ্টা করছি। যাইহোক, আপনাকে বলুন যে আপনার কাছে অন্য কোনও কোড রয়েছে যা কনস্ট্রাক্টরের বাইরে সমাধান ()টিকে কল করার চেষ্টা করছে (ওরফে ডিফার্ড অবজেক্ট) ... এটি ব্যতিক্রম হতে পারে এবং ধরা পড়তে
জন জ্যাকস 13

8
আমি এটিও নিশ্চিত নই যে এটি একটি খারাপ নকশা। প্রতিশ্রুতির বাইরে ফেলে দেওয়া একটি ত্রুটি প্রতিশ্রুতির মধ্যে ধরা পড়ার কথা নয়। এটি সম্ভবত ভুল ধারণা বা খারাপ বোঝার উদাহরণ, যদি ডিজাইনার আসলে ত্রুটিটি ধরা পড়ে বলে আশা করে।
কালে

3
এই সঠিক নির্মাণটি ইতিমধ্যে প্রশ্নের মধ্যে উল্লেখ করা হয়েছে। আপনি কি এটি পড়েছেন?
সিড্রিক রাইচেনবাচ

103

এখানে পার্টিতে দেরিতে বিট করুন তবে এটি করার অন্য একটি উপায় হ'ল ডিফার্ড অবজেক্ট ব্যবহার করা । আপনার কাছে মূলত সমান পরিমাণ বয়লারপ্লেট রয়েছে তবে আপনি যদি এগুলিকে পাশ দিয়ে যেতে চান এবং সম্ভবত তাদের সংজ্ঞা থেকে বাইরে সমাধান করতে চান তবে এটি সহজ।

নিষ্পাপ বাস্তবায়ন:

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|rejectনীতিগতভাবে দেওয়া হয়েছে বা এর মাধ্যমে নির্ধারিত হয়েছে তাতে কোনও ব্যবহারিক পার্থক্য নেই bind। এটি কেবলমাত্র জিকুয়েরি ডিফার্ড অবজেক্টের একটি সাধারণ বাস্তবায়ন যা 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

আমি @ জোনজাক্সের উত্তরটি পছন্দ করেছি তবে আমি এটিকে আরও একধাপ এগিয়ে নিয়ে যেতে চাইছি।

আপনি যদি আবদ্ধ হন 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 

আপডেট: আপনি বস্তুটি encapsulate করতে চান ক্ষেত্রে 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();

আপনি যদি অ্যাসিঙ্ক ফাংশনে এই উদাহরণগুলি ব্যবহার করেন, আপনি যখন প্রতিশ্রুতিবদ্ধ প্রতিশ্রুতির মানটি ব্যবহার করতে চান তখন আপনাকে প্রতিশ্রুতির সম্পত্তিটি উল্লেখ করতে হবে: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।
মিত

এটিই ওপি করেছে। বাস্তবে আপনি প্রতিশ্রুতিগুলির উপর ডিফার্ড প্যাটার্নটি পুনরায় উদ্ভাবন করছেন, অবশ্যই এটি সম্ভব এবং আপনার পদ্ধতির কাজ হয় (প্রাথমিক ওপি কোড হিসাবে) তবে গ্রহণযোগ্য উত্তরে বর্ণিত "থ্রো সুরক্ষা কারণ" এর কারণে এটি সেরা অভ্যাস নয়।
ধিল্ট

4

হ্যা, তুমি পারো. ব্যবহারের CustomEventব্রাউজার পরিবেশের জন্য API- টি। এবং নোড.জেএস পরিবেশে ইভেন্ট ইমিটার প্রকল্প ব্যবহার করা হচ্ছে ter যেহেতু প্রশ্নের স্নিপেট ব্রাউজার পরিবেশের জন্য, তাই এখানে তার কার্যকর উদাহরণ।

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;... এখনও ঠিক আছে।
মাইকে রডেন্ট 21

" প্রতিশ্রুতি নিজেই প্রসারিত করতে একটি ফাংশন সংযুক্ত করুন " " এটি করবেন না। প্রতিশ্রুতি ফলাফল মান, তাদের সমাধান করার ক্ষমতা তাদের দেওয়া উচিত নয়। আপনি চারপাশে এই বর্ধিত বেশী পাস করতে চান না।
বেরগি

2
কীভাবে সুযোগের বাইরে সমাধান করা যায় তা ছিল প্রশ্ন। এখানে একটি সমাধান রয়েছে যা কার্যকর হয় এবং আমাদের প্রযোজনায় আমাদের এটি করার একটি প্রয়োজনীয় কারণ ছিল। আমি দেখছি না যে উল্লিখিত সমস্যাটি সমাধান করা একটি ডাউনভোটের দাবিদার।
স্টিভেন স্পঞ্জিন

2

আমি নিজেকে ডিফার্ড প্যাটার্নটিও কিছু ক্ষেত্রে মিস করছি find আপনি সর্বদা একটি 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

যারা এই থ্রেডে পোস্ট করেছেন তাদের সবাইকে ধন্যবাদ। আমি একটি মডিউল তৈরি করেছি যার মধ্যে পূর্বে বর্ণিত ডিফার () অবজেক্টের পাশাপাশি এটিতে নির্মিত আরও কয়েকটি অবজেক্ট অন্তর্ভুক্ত রয়েছে। এগুলি সমস্ত প্রোগ্রামের মধ্যে যোগাযোগ / ইভেন্ট হ্যান্ডলিং বাস্তবায়নের জন্য প্রতিশ্রুতিগুলি এবং ঝরঝরে প্রতিশ্রুতি কল-ব্যাক সিনট্যাক্স le

  • মুলত: যে প্রতিশ্রুতি সমাধান করা যেতে পারে তা দূর থেকে ব্যর্থ হয়েছে (এর শরীরের বাইরে)
  • বিলম্ব: একটি প্রতিশ্রুতি যা নির্দিষ্ট সময়ের পরে স্বয়ংক্রিয়ভাবে সমাধান হয়ে যায়
  • টাইমআউট: প্রতিশ্রুতি যা একটি নির্দিষ্ট সময়ের পরে স্বয়ংক্রিয়ভাবে ব্যর্থ হয়।
  • চক্র: প্রতিশ্রুতি বাক্য গঠন সহ ইভেন্টগুলি পরিচালনা করার জন্য পুনরায় ট্রিগারযোগ্য প্রতিশ্রুতি
  • সারি: প্রতিশ্রুতি শৃঙ্খলার ভিত্তিতে মৃত্যুদন্ড কার্যকর করা কিউ।

    rp = require("repeatable-promise")

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


1

আমি এই জন্য একটি ছোট lib লিখেছি। 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

প্রথমে ব্রাউজার বা নোডে - নীল-নেটিজ-সিনট্যাক্স সক্ষম করুন

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'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.