Что я должен вернуть из этой асинхронной функции? - PullRequest
0 голосов
/ 04 октября 2018

Я обычный пользователь Обещаний в javascript.Теперь я хочу попробовать async / await.Но я застрял из-за половины знания async / await.

У меня есть функция, использующая Promise, следующим образом:

const asyncRequest = (funcA, b) => {
  // do some syncronous stuff. e. g. console.log
  console.log(b);
  return funcA(b)
    .then((something) => console.log(something))
    .catch((err) => console.log(err))
}

Я попытался преобразовать вышеуказанный код на основе Promise в async /await:

const asyncRequest = async (funcA, b) => {
  // do some syncronous stuff. e. g. console.log
  console.log(b);
  try {
    const something = await funcA(b);
    console.log(something);
  } catch (err) {
    console.log(err);
  }
}

Функция преобразования выглядит просто.Но я заметил, что в моем коде на основе Promise есть ключевое слово return.Но в моем асинхронном / ожидающем коде я запутался.Что я должен вернуть?

Реальный пример:

Пример, основанный на обещаниях

const Toast = {};

const createAsyncAction = ({
  asyncRequest, types, loadingPayload = null, showToastOnError = true,
}) => (dispatch) => {
  dispatch({
    type: types.loading,
    payload: loadingPayload,
  });

  return asyncRequest()
    .then((response) => {
      if (response.isMock) { // if mock request
        dispatch({
          type: types.success,
          payload: response.payload,
        });
        return;
      }

      if ([2, 3].includes(String(response.status).substring(0, 1))) { // if request succeeds
        response.json()
          .then((res) => {
            if (res.statusCode === 1000) {
              dispatch({
                type: types.success,
                payload: res.data,
              });
              return;
            }
            dispatch({ // if its a known error by server
              type: types.failure,
              payload: {
                code: res.statusCode,
                message: res.message,
              },
            });
            if (showToastOnError) {
              Toast.error(`${res.statusCode}: ${res.message}`);
            }
          }).catch((error) => { // if response is not convertible to json
            dispatch({
              type: types.failure,
              payload: {
                code: response.status,
                message: error.message,
              },
            });
            if (showToastOnError) {
              Toast.error(`${response.status}: ${error.message}`);
            }
          });
        return;
      }

      dispatch((error) => { // if request fails with some status codes like 404, 500...
        dispatch({
          type: types.failure,
          payload: {
            code: response.status,
            message: error.message,
          },
        });
        if (showToastOnError) {
          Toast.error(`${response.status}: ${error.message}`);
        }
      });
    }).catch(() => { // if request cannot be made due to some internet or connection issue
      dispatch({
        type: types.failure,
        payload: {
          code: 0,
          message: 'Connection issue. Make sure your are connected to the internet and that your API is working',
        },
      });
      if (showToastOnError) {
        Toast.error('Connection issue. Make sure your are connected to the internet and that your API is working');
      }
    });
};

export default createAsyncAction;

Асинхронное / ожиданиепример:

const Toast = {};

const createAsyncAction = ({
  asyncRequest, types, loadingPayload = null, showToastOnError = true,
}) => async (dispatch) => {
  dispatch({
    type: types.loading,
    payload: loadingPayload,
  });

  try {
    const response = await asyncRequest();
    if (response.isMock) { // if mock request
      dispatch({
        type: types.success,
        payload: response.payload,
      });
      return;
    }

    if ([2, 3].includes(String(response.status).substring(0, 1))) { // if request succeeds
      try {
        const jsonResponse = await response.json();
        if (jsonResponse.statusCode === 1000) {
          dispatch({
            type: types.success,
            payload: jsonResponse.data,
          });
          return;
        }
        dispatch({ // if its a known error by server
          type: types.failure,
          payload: {
            code: jsonResponse.statusCode,
            message: jsonResponse.message,
          },
        });
        if (showToastOnError) {
          Toast.error(`${jsonResponse.statusCode}: ${jsonResponse.message}`);
        }
      } catch (error) {
        dispatch({
          type: types.failure,
          payload: {
            code: response.status,
            message: error.message,
          },
        });
        if (showToastOnError) {
          Toast.error(`${response.status}: ${error.message}`);
        }
      }
      return;
    }

    dispatch((error) => { // if request fails with some status codes like 404, 500...
      dispatch({
        type: types.failure,
        payload: {
          code: response.status,
          message: error.message,
        },
      });
      if (showToastOnError) {
        Toast.error(`${response.status}: ${error.message}`);
      }
    });
  } catch (_) {
    dispatch({
      type: types.failure,
      payload: {
        code: 0,
        message: 'Connection issue. Make sure your are connected to the internet and that your API is working',
      },
    });
    if (showToastOnError) {
      Toast.error('Connection issue. Make sure your are connected to the internet and that your API is working');
    }
  }
};

export default createAsyncAction;

Ответы [ 3 ]

0 голосов
/ 04 октября 2018

Обе функции возвращают обещания.

В первом случае это происходит потому, что вы возвращаете цепочку обещаний.Во втором случае это потому, что все функции async возвращают Promises по определению.Таким образом, сообщение «вернуть обещание» подразумевается во второй функции.

Когда вы возвращаете значение из функции async, это значение, с которым разрешается обещание.Если вы ничего не возвращаете, обещание разрешается со значением undefined.В этом контексте это фактически значение, возвращаемое функцией .then((something) => console.log(something)).Это, конечно, undefined, поэтому вам не нужно ничего возвращать.

0 голосов
/ 04 октября 2018

Вам не нужен возврат.Это не причина различий в вашем коде.В вашем примере вам нужно использовать await при вызове funcA (b), поскольку вы хотите, чтобы js делал другие вещи, пока он разрешается.

const asyncRequest = async (funcA, b) => {
  // do some syncronous stuff. e. g. console.log
  console.log(b);
  try {
    const something = await funcA(b);
    console.log(something);
  } catch (err) {
    console.log(err);
  }
}
0 голосов
/ 04 октября 2018

Вам не нужно!

Любая функция, отмеченная как async, всегда будет возвращать обещание.Теперь, если вы хотите, чтобы это обещание разрешило что-то, вам нужно будет вернуть значение.Тем не менее, поскольку вы просто делаете console.log, который имеет возвращаемое значение undefined, это равносильно возврату ничего (поскольку JavaScript неявно вернет undefined, если не указано возвращаемое значение).

Из async документов :

Асинхронная функция - это функция, которая работает асинхронно через цикл событий, используя неявный Promise для возврата своего результата.

Итак, async будет неявно возвращать любое возвращаемое значение из функции, заключенной в Promise.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...