Promise.resolve 대 새로운 Promise (resolve)


97

블루 버드를 사용하고 있으며 동기 함수를 Promise로 해결하는 두 가지 방법이 있지만 두 가지 방법의 차이점을 이해하지 못합니다. 스택 트레이스가 약간 다른 것처럼 보이므로, 그렇지 alias않습니까?

그렇다면 선호하는 방법은 무엇입니까?

웨이 A

function someFunction(someObject) {
  return new Promise(function(resolve) {
    someObject.resolved = true;
    resolve(someObject);
  });
}

웨이 B

function someFunction(someObject) {
  someObject.resolved = true;
  return Promise.resolve(someObject);
}

3
Promise.resolve그냥 설탕입니다.
Qantas 94 Heavy

1
짧은 대답-사용법에 차이가 없습니다. 그냥 설탕.
Pinal

@Pinal "설탕"은 무엇입니까?
doubleOrt

6
@ 황소 자리. Syntactic sugar 는 일을 더 쉽게 읽고 표현할 수 있도록 설계된 구문입니다. 참조 : wikipedia .
Wyck

답변:


85

댓글의 두 답변과는 달리 차이가 있습니다.

동안

Promise.resolve(x);

기본적으로 다음과 같습니다.

new Promise(function(r){ r(x); });

미묘함이 있습니다.

Promise 반환 함수는 일반적으로 비동기 적으로 throw 될 수 있으므로 동 기적으로 throw되지 않아야한다는 보장이 있어야합니다. 예상치 못한 결과와 경쟁 조건을 방지하기 위해 일반적으로 던지는 거부로 변환됩니다.

이를 염두에두고-스펙이 생성되었을 때 promise 생성자는 안전하게 던져집니다.

어떤 경우 someObject이다 undefined?

  • Way A는 거부 된 약속을 반환합니다.
  • 방법 B는 동 기적으로 던집니다.

Bluebird는 이것을 보았고 Petka는 Promise.method이 문제를 해결하기 위해 추가하여 반환 값을 계속 사용할 수 있습니다. 따라서 Bluebird에서 이것을 작성하는 정확하고 쉬운 방법은 실제로 둘 다 아닙니다.

var someFunction = Promise.method(function someFunction(someObject){
    someObject.resolved = true;
    return someObject;
});

Promise.method는 throw를 거부로 변환하고 해결로 돌아갑니다. 이 작업을 수행하는 가장 안전한 방법이며 then반환 값을 통해 능력을 동화 하므로 someObject실제로 약속 자체 인 경우에도 작동 합니다.

일반적으로 Promise.resolvePromise에 대한 객체 및 외부 Promise (thenables)를 캐스팅하는 데 사용됩니다. 그것이 유스 케이스입니다.


"Promise returning functions는 일반적으로 비동기 적으로 던져 질 수 있으므로 동 기적으로 던져서는 안된다는 보장을 가져야합니다." 왜 함수가 동기식 또는 비동기식이어야하지만 둘 다가 아니어야하는지 확장 할 수 있습니까? 현재 Promise.resolve ()를 즐기고 있습니다. 사용하는 Promise.resolve()것이 안티 패턴 이라고 말할 수 있습니까?
Ashley Coolman

2
참조 @AshleyCoolman blog.izs.me/post/59142742143/designing-apis-for-asynchrony - 방법 때로는 한다 비동기 적으로 작동 항상 일관성을 위해 그렇게합니다.
Benjamin Gruenbaum

를 사용하는 것과 같은 방식으로 Promise.resolve()의 새 인스턴스를 생성 합니까 ? 그렇지 않은 경우 더 빠르고 동기식 던지기를 피할 수 있습니다. Promisenewreturn Promise.resolve(yourCode)
Steven Vachon 16.

1
기분이 좋지 않습니다. "Promise.resolve (). then (function () {/ * 오류를 던질 수있는 경우 * /}). then ..."을 사용하여 오류가 거부 된 약속이되는지 확인합니다. "Promise.method"에 대해 자세히 살펴 보겠습니다
Polopollo

1
@Polopollo 또는 Promise.coroutine훨씬 더 유용합니다.
Benjamin Gruenbaum

17

위의 답변이나 의견에서 언급되지 않은 또 다른 차이점이 있습니다.

경우 someObject이다 Promise, new Promise(resolve)두 개의 추가 틱을 요할 것입니다.


다음 두 코드 스 니펫을 비교하십시오.

const p = new Promise(resovle => setTimeout(resovle));

new Promise(resolve => resolve(p)).then(() => {
  console.log("tick 3");
});

p.then(() => {
  console.log("tick 1");
}).then(() => {
  console.log("tick 2");
});

const p = new Promise(resovle => setTimeout(resovle));

Promise.resolve(p).then(() => {
  console.log("tick 3");
});

p.then(() => {
  console.log("tick 1");
}).then(() => {
  console.log("tick 2");
});

두 번째 스 니펫은 먼저 'tick 3'을 인쇄합니다. 왜?

  • 값이 약속이면 Promise.resolve(value)정확하게 값을 반환합니다. Promise.resolve(value) === value사실입니다. MDN 참조

  • 그러나 new Promise(resolve => resolve(value))약속을 따르기 위해 고정 된 새로운 약속을 반환합니다 value. '잠금'을 만들기 위해서는 추가 1 틱이 필요합니다.

    // something like:
    addToMicroTaskQueue(() => {
      p.then(() => {
        /* resolve newly promise */
      })
        // all subsequent .then on newly promise go on from here
        .then(() => {
          console.log("tick 3");
        });
    });
    

    tick 1 .then전화가 먼저 실행됩니다.


참조 :

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.