Javascript Promises nest deeply just like callbacks

I am trying to use Promises with my async functions. From my understanding promises are supposed to alleviate callback hell. However it seems my code is still very deeply nested.

Am I missing something about promises (could this be rewritten to be more readable/idiomatic) or do promises nest just like callbacks sometimes?

In this example I'm building a function that calls an API to retrieve a friends list from some social media account. If it the initial call fails due to authentication errors, I know I have to authenticate first and do the call again.

const myRequest = { /* custom instance of 'request-promise' */ }

function getFriendsList() {
  return new Promise((resolve, reject) => {
    myRequest.get('/getFriendList').then(resp => {
      if (needsAuthentication(resp)) {
        myRequest.post('/auth', credentials).then(() => {
          myRequest.get('/getFriendList').then(resp => resolve(resp.body))
        }).catch(err => {
          reject(err)
        })
      } else {
        resolve(resp.body)
      }
    }).catch(err => {
      reject(err)
    })
  })
}

function authenticate() {
  return new Promise((resolve, reject) => {
    getCredentials().then(credentials => {
      myRequest.post('/auth').then(resp => {
        return resp.statusCode == '200' ? resolve(resp) : reject(resp)
      })    
    }).catch(err => reject(err))
  })
}

If a Promise is resolved with a Promise, itself does not resolve but rather waits for the passed Promise to resolve. So the Promise chain is flattened. Same applies to returning a Promise from a then chain. That's quite useful:

function getFriendsList() {
  return myRequest.get('/getFriendList').then(resp => {
    if (needsAuthentication(resp)) {
      return myRequest.post('/auth', credentials).then(() => 
        myRequest.get('/getFriendList').then(resp => resp.body)
      );         
    } else {
      return resp.body;
    }
  });
}

function authenticate() {
  return getCredentials()
    .then(credentials => myRequest.post('/auth'))
    .then(resp => {
      if(resp.statusCode == '200'){
        return resp;
      } else {
        throw resp;
      }
    })    
}

To prevent

callback hell

We have the Promise way, but now to prevent the

Promise hell

We have the async/await syntax

Your code should be like this

async function getFriendsList() {
    var resp = await myRequest.get('/getFriendList')
    if (needsAuthentication(resp)) {
        await myRequest.post('/auth', credentials)
        var resp2 = await myRequest.get('/getFriendList')
        return resp2.body
    } else {
        return resp.body
    }
}

async function authenticate() {
    var credentials = await getCredentials()
    var resp = await myRequest.post('/auth')
    return resp
}

Always remember that any Promise.reject() or any throw Error inside your async function will result in a rejected function (Promise).

So, in your authenticate function

async function authenticate() {
    var credentials = await getCredentials()
    var resp = await myRequest.post('/auth') //If this get rejected
    return resp
}

authenticate().then().catch(error => console.log('error here', error))

Always remember

async functions are just Promises , that resolve with the return and reject when inside its code something reject or throw an Error

链接地址: http://www.djcxy.com/p/9452.html

上一篇: 承诺如何在这种情况下实施?

下一篇: Javascript Promises嵌套深度就像回调