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

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