如何在 ES6 承诺中使用递归?

How to use recursion within a ES6 promise?

我想使用 axios get 请求检查具有新设置 ID 的 post 是否已经存在。 (我是在前端做的,因为我不控制后端)

但是,当具有该 id 的 posts 已经存在并且它在 promise 中时,我不确定如何组合我想要的递归。

这是我目前得到的:

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);
      }
    });
}

这是它的工作原理:

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();

我重写了一点以便自己测试和理解它,所以希望你能把它改回来:)。

几个问题:

  • getUniqueId 应该是一个函数,因为每次调用 newPost 时您都希望获得一个新 ID。

  • 您不应该使用 promise constructor antipattern:不要创建新的承诺,而只是 return 承诺本身,或者在需要时 throw拒绝。

这是更正后的代码:

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
            }
        });
}