简体   繁体   中英

How to use recursion within a ES6 promise?

I want to check if a post with a newly set id already exists using an axios get request. (I am doing this on the front-end because I don't control the back-end)

However I am not sure how to combine the recursion I want for when a posts with that id already exists and the promise it is in.

This is what I got so far:

import axios from 'axios';
import uuidv4 from 'uuid/v4';

export function newPost(post) {
  return (dispatch) => {
    getUniqueId.then((id) => {
      // post new post with unique id
      // dispatch({ type: NEW_POST_FULFILLED, payload: err });
    }).catch((err) => {
      dispatch({ type: NEW_POST_FAILED, payload: err });
    })
  }
}

const getUniqueId = new Promise((resolve, reject) => {
  checkUniqueId(resolve, reject, uuidv4())
});

const checkUniqueId = (resolve, reject, id) => {
  axios
    .get(`${api}/posts/${id}`, { headers })
    .then((resp) => checkUniqueId(resolve, reject, uuidv4()))
    .catch((err) => {
      if(err.response.status === 500) {
        resolve(id);
      } else {
        reject(err);
      }
    });
}

A few issues:

  • getUniqueId should be a function, since you would want to get a new id every time newPost is called.

  • You should not use the promise constructor antipattern : don't create a new promise, but instead just return the promise itself, or throw when you need to reject.

Here is the corrected code:

export function newPost(post) {
    return (dispatch) => {
        // Call as function!
        getUniqueId().then((id) => {
            // post new post with unique id
            // dispatch({ type: NEW_POST_FULFILLED, payload: err });
        }).catch((err) => {
            dispatch({ type: NEW_POST_FAILED, payload: err });
        })
    }
}

// Define as function, and just return the promise from `checkUniqueId`
const getUniqueId = _ => checkUniqueId(uuidv4());

const checkUniqueId = (id) => {
    // return the promise!
    return axios
        .get(`${api}/posts/${id}`, { headers })
        .then((resp) => checkUniqueId(uuidv4()))
        .catch((err) => {
            if (err.response.status === 500) {
                return id;
            } else {
                throw err; // throw the error to cascade it through the chain
            }
        });
}

Here is how this could work:

 var i = 0; function newPost() { getUniqueId().then(function(id) { console.log('got it: ' + id); }); } function getUniqueId() { return checkUniqueId(i).catch(function() { console.log('id ' + i + ' is already in use'); i++; return getUniqueId(); }); } function checkUniqueId(id) { return new Promise(function(resolve, reject) { if (i < 2) { reject(); } else { resolve(id); } }); } newPost(); 

I rewrote it a bit to be able to test and understand it myself, so hopefully you're able to transform this back :).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM