Programing

개체가 약속인지 어떻게 알 수 있습니까?

lottogame 2020. 3. 21. 10:09
반응형

개체가 약속인지 어떻게 알 수 있습니까?


ES6 Promise이든 블루 버드 Promise, Q Promise 등

주어진 개체가 약속인지 확인하려면 어떻게합니까?


약속 라이브러리가 결정하는 방법

.then함수 가있는 경우 - 표준 약속 라이브러리 사용합니다.

Promises / A + 사양에는 then기본적으로 " then메소드가 있는 객체" able 이라는 개념 있습니다. 약속은 그때의 방법으로 무엇이든 받아 들일 것 입니다. 언급 한 모든 약속 구현 이이 작업을 수행합니다.

우리가 사양 을 보면 :

2.3.3.3 then함수 인 경우 x를 사용하여이를 호출하고 첫 번째 인수 resolvePromise 및 두 번째 인수 rejectPromise

또한이 디자인 결정의 근거를 설명합니다.

이러한 능력의 처리는 then약속 / A + 호환 then방법 을 노출하는 한 약속 구현이 상호 운용되도록합니다 . 또한 Promises / A + 구현은 부적합한 구현을 합리적인 방법으로 "어셈블리"할 수 있습니다.

어떻게 결정해야합니까

당신은 안 - 대신 전화 Promise.resolve(x)( Q(x)것 Q에) 항상 값 또는 외부 변환 then신뢰할 수있는 약속으로 할 수 있습니다. 이러한 점검을 직접 수행하는 것보다 안전하고 쉽습니다.

정말로 확실해야합니까?

항상 테스트 스위트를 통해 실행할 수 있습니다 . : D


무언가 약속이 불필요하게 코드를 복잡하게 만드는지 확인하십시오. Promise.resolve

Promise.resolve(valueOrPromiseItDoesntMatter).then(function(value) {

})

다음 은 약속을 테스트하는 방법으로 사양에서 비준 된 원래의 대답입니다 .

Promise.resolve(obj) == obj

이것은 알고리즘 이 스펙의 정의에 의해 약속 된 경우에만Promise.resolve 전달 된 정확한 객체를 반환하도록 명시 적으로 요구 하기 때문에 작동 합니다 .

여기에 다른 대답이 있습니다.이 말은 Safari에서 작동하지 않을 때 다른 것으로 변경했습니다. 1 년 전이었으며 이제 Safari에서도 안정적으로 작동합니다.

나는 지금보다 더 많은 사람들이 그 대답에서 변경된 해결책에 투표 한 것을 감안할 때, 잘못된 생각을 제외하고는 나의 원래의 대답을 편집했을 것입니다. 이것이 더 나은 답변이라고 믿습니다.


업데이트 : 이것은 더 이상 최선의 대답이 아닙니다. 대신 다른 답변을 투표하십시오 .

obj instanceof Promise

해야합니다. 이는 기본 es6 약속에서만 안정적으로 작동 할 수 있습니다.

shim, promise 라이브러리 또는 promise와 비슷한 척하는 것을 사용하는 경우 .then여기에있는 다른 답변에서 볼 수 있듯이 "thenable"( 방법이있는 항목) 을 테스트하는 것이 더 적절할 수 있습니다 .


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

주어진 객체가 ES6 Promise인지 확인하기 위해이 술어를 사용할 수 있습니다.

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

CalltoString에서 직접을 보내면 주어진 객체 유형의 기본 문자열 표현Object.prototype반환 됩니다. 이것은 주어진 객체가"[object Promise]"

  • 다음과 같은 오 탐지를 무시합니다.
    • 생성자 이름이 동일한 자체 정의 개체 유형 ( "Promise")
    • toString주어진 객체의 자체 작성 방법.
  • 또는 과 달리instanceof 여러 환경 컨텍스트 (예 : iframe) 에서 작동 isPrototypeOf합니다.

그러나, 어떤 특정 호스트 오브젝트 의 있으며, 태그를 통해 개질은Symbol.toStringTag , 반환 할 "[object Promise]". 이는 프로젝트에 따라 의도 된 결과 일 수도 있고 아닐 수도 있습니다 (예 : 사용자 정의 Promise 구현이있는 경우).


객체가 기본 ES6 Promise 에서 온 것인지 확인하려면 다음을 사용할 수 있습니다.

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 
}

따르면 이러한 그리고 이 섹션 사양의 기능의 문자열 표현되어야한다 :

"함수 식별자 ( FormalParameterList opt ) { FunctionBody }"

위의 내용에 따라 처리됩니다. FunctionBody는 것입니다 [native code]모든 주요 브라우저에서.

MDN : Function.prototype.toString

이것은 여러 환경 컨텍스트에서도 작동합니다.


전체 질문에 대한 대답은 아니지만 Node.js 10에서 isPromise객체가 기본 약속인지 여부를 확인 하는 새로운 util 함수 가 추가 되었다는 것을 언급 할 가치가 있다고 생각합니다 .

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

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

다음은 코드 형식입니다 https://github.com/ssnau/xkit/blob/master/util/is-promise.js

!!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';

then메소드 가있는 오브젝트 인 경우 로 취급해야합니다 Promise.


비동기 방식이라면이 작업을 수행하고 모호성을 피할 수 있습니다.

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

함수가 promise를 반환하면 확인 된 값으로 기다렸다가 반환됩니다. 함수가 값을 반환하면 해결 된 것으로 간주됩니다.

함수가 오늘 약속을 반환하지 않지만 내일이 약속을 반환하거나 비동기로 선언되면 미래를 보장 할 수 있습니다.


당신이 사용하는 경우 타이프 라이터를 , 난 당신이 "유형 술어"기능을 사용할 수있는 추가하고 싶습니다. 논리 검증을 리턴하는 함수로 랩핑하면 x is Promise<any>타입 캐스트를 수행 할 필요가 없습니다. 아래 예 c는 약속 또는 c.fetch()메서드 를 호출하여 약속으로 변환하려는 유형 중 하나입니다 .

export function toPromise(c: Container<any> | Promise<any>): Promise<any> {
    if (c == null) return Promise.resolve();
    return isContainer(c) ? c.fetch() : c;
}

export function isContainer(val: Container<any> | Promise<any>): val is Container<any> {
    return val && (<Container<any>>val).fetch !== undefined;
}

export function isPromise(val: Container<any> | Promise<any>): val is Promise<any> {
    return val && (<Promise<any>>val).then !== undefined;
}

추가 정보 : https://www.typescriptlang.org/docs/handbook/advanced-types.html


이것은 graphql-js 패키지가 약속을 감지 하는 방법입니다 .

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

value함수의 반환 값입니다. 내 프로젝트 에서이 코드를 사용하고 있으며 지금까지 아무런 문제가 없습니다.


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));
});

비동기 함수 또는 약속 을 감지 하는 신뢰할 수있는 방법을 찾은 후에 다음 테스트를 사용했습니다.

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

ES6 :

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

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

참고 URL : https://stackoverflow.com/questions/27746304/how-do-i-tell-if-an-object-is-a-promise

반응형