developer tip

내 비동기 함수가 Promise {를 반환하는 이유는 무엇입니까?

copycodes 2020. 10. 10. 10:13
반응형

내 비동기 함수가 Promise {를 반환하는 이유는 무엇입니까? } 값 대신?


내 코드 :

let AuthUser = data => {
  return google.login(data.username, data.password).then(token => { return token } )
}

그리고 다음과 같이 실행하려고 할 때 :

let userToken = AuthUser(data)
console.log(userToken)

나는 얻는다 :

Promise { <pending> }

그런데 왜?

내 주요 목표는 google.login(data.username, data.password)약속을 반환하는 토큰을 변수로 가져 오는 것입니다 . 그리고 나서야 몇 가지 조치를 취할 수 있습니다.


약속은 결과가 아직 해결되지 않는 한 항상 보류 중으로 기록됩니다. .then약속 상태 (해결됨 또는 아직 보류 중)에 관계없이 결과를 캡처하려면 약속을 호출해야합니다 .

let AuthUser = function(data) {
  return google.login(data.username, data.password).then(token => { return token } )
}

let userToken = AuthUser(data)
console.log(userToken) // Promise { <pending> }

userToken.then(function(result) {
   console.log(result) // "Some User token"
})

왜 그런 겁니까?

약속은 전진 ​​방향 일뿐입니다. 한 번만 해결할 수 있습니다. a의 확인 된 값이 Promise해당 .then또는 .catch메서드에 전달됩니다 .

세부

Promises / A + 사양에 따르면 :

Promise 해결 절차는 Promise와 값을 입력으로받는 추상 연산으로, [[Resolve]] (promise, x)로 표시합니다. x가 thenable이면 x가 적어도 약속처럼 행동한다는 가정하에 promise가 x의 상태를 채택하도록 시도합니다. 그렇지 않으면 x 값으로 약속을 이행합니다.

이러한 thenables 처리를 통해 Promise / A + 호환 then 메서드를 노출하는 한 promise 구현이 상호 운용 될 수 있습니다. 또한 Promises / A + 구현이 합리적인 then 메서드로 부적합 구현을 "동화"할 수 있습니다.

이 사양은 파싱하기가 조금 어렵 기 때문에 분석해 보겠습니다. 규칙은 다음과 같습니다.

에서 함수 경우 .then핸들러는 값, 다음 반환 Promise하는 값을 해결합니다. 핸들러가 다른 것을 반환 Promise하면 원래 Promise는 체인의 해결 된 값으로 해결 Promise됩니다. 다음 .then처리기는 항상 이전에서 반환 된 연결 약속의 확인 된 값을 포함합니다 .then.

실제로 작동하는 방식은 아래에 자세히 설명되어 있습니다.

1. .then함수 의 반환은 약속의 해결 된 값이됩니다.

function initPromise() {
  return new Promise(function(res, rej) {
    res("initResolve");
  })
}

initPromise()
  .then(function(result) {
    console.log(result); // "initResolve"
    return "normalReturn";
  })
  .then(function(result) {
    console.log(result); // "normalReturn"
  });

2. .then함수가를 반환하면 Promise연결된 프라 미스의 확인 된 값이 다음으로 전달됩니다 .then.

function initPromise() {
  return new Promise(function(res, rej) {
    res("initResolve");
  })
}

initPromise()
  .then(function(result) {
    console.log(result); // "initResolve"
    return new Promise(function(resolve, reject) {
       setTimeout(function() {
          resolve("secondPromise");
       }, 1000)
    })
  })
  .then(function(result) {
    console.log(result); // "secondPromise"
  });

I know this question was asked 2 years ago but i run into the same issue and the answer for the problem is since ES6, that you can simply await the functions return value, like:

let AuthUser = function(data) {
  return google.login(data.username, data.password).then(token => { return token } )
}

let userToken = await AuthUser(data)
console.log(userToken) // your data

The then method returns a pending promise which can be resolved asynchronously by the return value of a result handler registered in the call to then, or rejected by throwing an error inside the handler called.

So calling AuthUser will not suddenly log the user in synchronously, but returns a promise whose then registered handlers will be called after the login succeeds ( or fails). I would suggest triggering all login processing by a then clause of the login promise. E.G. using named functions to highlight the sequence of flow:

let AuthUser = data => {   // just the login promise
  return google.login(data.username, data.password);
};

AuthUser(data).then( processLogin).catch(loginFail);

function processLogin( token) {
      // do logged in stuff:
      // enable, initiate, or do things after login
}
function loginFail( err) {
      console.log("login failed: " + err);
}

See the MDN section on Promises. In particular, look at the return type of then().

To log in, the user-agent has to submit a request to the server and wait to receive a response. Since making your application totally stop execution during a request round-trip usually makes for a bad user experience, practically every JS function that logs you in (or performs any other form of server interaction) will use a Promise, or something very much like it, to deliver results asynchronously.

Now, also notice that return statements are always evaluated in the context of the function they appear in. So when you wrote:

let AuthUser = data => {
  return google
    .login(data.username, data.password)
    .then( token => {
      return token;
    });
};

the statement return token; meant that the anonymous function being passed into then() should return the token, not that the AuthUser function should. What AuthUser returns is the result of calling google.login(username, password).then(callback);, which happens to be a Promise.

Ultimately your callback token => { return token; } does nothing; instead, your input to then() needs to be a function that actually handles the token in some way.


Your Promise is pending, complete it by

userToken.then(function(result){
console.log(result)
})

after your remaining code. All this code does is that .then() completes your promise & captures the end result in result variable & print result in console. Keep in mind, you cannot store the result in global variable. Hope that explanation might help you.

참고URL : https://stackoverflow.com/questions/38884522/why-is-my-asynchronous-function-returning-promise-pending-instead-of-a-val

반응형