javascript - मैं कैसे बताऊं कि कोई वस्तु एक वादा है?




promise q (10)

चाहे वह ईएस 6 प्रॉमिस हो या ब्लूबर्ड प्रॉमिस, क्यू प्रॉमिस आदि।

मैं यह देखने के लिए परीक्षण कैसे करूं कि कोई दी गई वस्तु एक वादा है?


एक वादा पुस्तकालय कैसे तय करता है

यदि इसका एक .then फ़ंक्शन है - .then यह एकमात्र मानक वादा पुस्तकालयों का उपयोग है।

प्रॉमिस / ए + विनिर्देश में एक धारणा है जिसे then सक्षम किया गया है जो मूल रूप से "एक then विधि के साथ एक वस्तु" है। वादा करता है और फिर एक विधि के साथ कुछ भी आत्मसात करना चाहिए। आपके द्वारा किए गए वादे के क्रियान्वयन के सभी लोग ऐसा करते हैं।

यदि हम specification :

2.3.3.3 यदि कोई कार्य है, तो इसे x के साथ इस रूप में कहें, पहला तर्क हल करें, और दूसरा तर्क अस्वीकार करें।

यह इस डिजाइन निर्णय के औचित्य की भी व्याख्या करता है:

then एबल्स के इस उपचार से इंटरप्रिटेशन के लिए वादे के क्रियान्वयन की अनुमति मिलती है, जब तक कि वे एक प्रॉमिस / A + -compliant - विधि का खुलासा नहीं करते। यह वादा करता है / ए + कार्यान्वयन के लिए उचित तो तरीकों के साथ गैर-अनुरूप कार्यान्वयन को "आत्मसात" करने की अनुमति देता है।

आपको कैसे तय करना चाहिए

आपको नहीं करना चाहिए - इसके बजाय Promise.resolve(x) ( Q(x) Q) में कॉल करें जो हमेशा किसी भी मूल्य या बाहरी को then एक विश्वसनीय वादे में सक्षम कर देगा। इन जाँचों को स्वयं करना अधिक सुरक्षित और आसान है।

वास्तव में सुनिश्चित करने की आवश्यकता है?

आप इसे हमेशा टेस्ट सूट के माध्यम से चला सकते हैं: डी


ES6:

const promise = new Promise(resolve => resolve('olá'));

console.log(promise.toString().includes('Promise')); //true

इस तरह से graphql-js पैकेज वादों का पता लगाता है:

it('should return a promise', function() {
    var result = testedFunctionThatReturnsPromise();
    expect(result).toBeDefined();
    // 3 slightly different ways of verifying a promise
    expect(typeof result.then).toBe('function');
    expect(result instanceof Promise).toBe(true);
    expect(result).toBe(Promise.resolve(result));
});

value आपके फ़ंक्शन का दिया गया मान है। मैं अपने प्रोजेक्ट में इस कोड का उपयोग कर रहा हूं और मुझे अब तक कोई समस्या नहीं है।


पूर्ण प्रश्न का उत्तर नहीं है, लेकिन मुझे लगता है कि यह उल्लेख के लायक है कि Node.js 10 में एक नया उपयोग फ़ंक्शन जिसे isPromise कहा जाता है, जोड़ा गया है जो यह जांचता है कि कोई वस्तु एक देशी वादा है या नहीं:

const utilTypes = require('util').types
const b_Promise = require('bluebird')

utilTypes.isPromise(Promise.resolve(5)) // true
utilTypes.isPromise(b_Promise.resolve(5)) // false

यदि आप एक async विधि में हैं, तो आप ऐसा कर सकते हैं और किसी भी अस्पष्टता से बच सकते हैं।

async myMethod(promiseOrNot){
  const theValue = await promiseOrNot()
}

यदि फ़ंक्शन प्रतिज्ञा देता है, तो वह प्रतीक्षा करेगा और हल किए गए मान के साथ लौटेगा। यदि फ़ंक्शन मान लौटाता है, तो इसे हल के रूप में माना जाएगा।

यदि फ़ंक्शन आज एक वादा वापस नहीं करता है, लेकिन कल एक रिटर्न देता है या उसे एसिंक्स्ट घोषित किया जाता है, तो आप भविष्य के प्रमाण होंगे।


यह देखने के लिए कि क्या दी गई वस्तु ES6 वादा है , हम इस विधेय का उपयोग कर सकते हैं:

function isPromise(p) {
  return p && Object.prototype.toString.call(p) === "[object Promise]";
}

Object.prototype से सीधे Call toString दिए गए ऑब्जेक्ट प्रकार का एक मूल स्ट्रिंग प्रतिनिधित्व लौटाता है जो हमारे मामले में "[object Promise]" है। यह सुनिश्चित करता है कि दी गई वस्तु

  • इस तरह के रूप में झूठी सकारात्मक बाईपास:
    • एक ही निर्माता के नाम ("वादा") के साथ स्व-परिभाषित ऑब्जेक्ट प्रकार।
    • दी गई वस्तु का स्व-लिखित toString विधि।
  • isPrototypeOf या isPrototypeOf विपरीत कई पर्यावरण संदर्भों (जैसे iframes) पर काम करता है।

हालाँकि, कोई भी विशेष होस्ट ऑब्जेक्ट , जिसका Symbol.toStringTag माध्यम से संशोधित किया Symbol.toStringTag , वह "[object Promise]" वापस कर सकता है। यह अपेक्षित परिणाम हो सकता है या परियोजना के आधार पर नहीं हो सकता है (जैसे कि कोई कस्टम वादा लागू हो)।

यह देखने के लिए कि ऑब्जेक्ट देशी ES6 प्रॉमिस से है , हम उपयोग कर सकते हैं:

function isNativePromise(p) {
  return p && typeof p.constructor === "function"
    && Function.prototype.toString.call(p.constructor).replace(/\(.*\)/, "()")
    === Function.prototype.toString.call(/*native object*/Function)
      .replace("Function", "Promise") // replacing Identifier
      .replace(/\(.*\)/, "()"); // removing possible FormalParameterList 
}

this और इस खंड के अनुसार, फ़ंक्शन का स्ट्रिंग प्रतिनिधित्व होना चाहिए:

"फंक्शन आइडेंटिफ़ायर ( फॉर्मलपैरिमेलिस्ट ऑप्ट ) { फंक्शनबॉडी }"

जो ऊपर के अनुसार संभाला जाता है। फंक्शनबॉडी सभी प्रमुख ब्राउज़रों में [native code] है।

MDN: Function.prototype.toString .prototyp.toString

यह कई पर्यावरण संदर्भों के साथ-साथ काम करता है।


यहाँ मेरा मूल उत्तर दिया गया है, जो बाद में एक वादे के लिए परीक्षण करने के तरीके के रूप में पुष्टि की गई है :

Promise.resolve(obj) == obj

यह काम करता है क्योंकि एल्गोरिथ्म स्पष्ट रूप से मांग करता है कि Promise.resolve में यदि और केवल कल्पना के माध्यम से वादा किया गया है, तो उसमें पारित की गई सटीक वस्तु को वापस करना होगा।

मेरे पास यहाँ एक और उत्तर है, जो यह कहता था, लेकिन मैंने इसे उस समय कुछ और के लिए बदल दिया जब यह सफारी के साथ काम नहीं करता था। यह एक साल पहले था, और यह अब सफारी में भी मज़बूती से काम करता है।

मैंने अपना मूल उत्तर संपादित किया होगा, सिवाय इसके कि गलत लगा, यह देखते हुए कि अब तक मूल से अधिक लोगों ने उस उत्तर में परिवर्तित समाधान के लिए मतदान किया है। मेरा मानना ​​है कि यह बेहतर उत्तर है, और मुझे आशा है कि आप सहमत होंगे।


Async फ़ंक्शन या यहां तक ​​कि वादे का पता लगाने के लिए विश्वसनीय तरीके से खोज करने के बाद, मैंने निम्नलिखित परीक्षण का उपयोग किया:

() => fn.constructor.name === 'Promise' || fn.constructor.name === 'AsyncFunction'

function isPromise(value) {
  return Boolean(value && typeof value.then === 'function');
}

if (typeof thing.then === 'function') {
    // probably a promise
} else {
    // definitely not a promise
}




es6-promise