简体   繁体   English

如何在FP(Ramda.js)中重写此函数?

[英]How to rewrite this function in FP (Ramda.js)?

I have this function and I wonder, how should one write it in FP style (with Ramda.js). 我有这个功能,我想知道如何用FP风格(用Ramda.js)编写它。

  1. registerUser(username, password) -> client_id, client_secret; registerUser(用户名,密码)-> client_id,client_secret;
  2. getUserAccessToken(username, password, client_id, client_secret) -> access_token, refresh_token, refreshTokenExpiresAt; getUserAccessToken(用户名,密码,client_id,client_secret)-> access_token,refresh_token,refreshTokenExpiresAt;
  3. save to storage: client_id, client_secret, access_token, refresh_token, refreshTokenExpiresAt. 保存到存储:client_id,client_secret,access_token,refresh_token,refreshTokenExpiresAt。
async function registerUser(username: string, password: string) {
  try {
    const { client_id, client_secret } = await authAPI.registerUser(username, password);

    // get tokens
    const {
      access_token,
      refresh_token,
      refreshTokenExpiresAt,
    } = await authAPI.getUserAccessToken(username, password, client_id, client_secret);

    // save to async storage
    store.update('user', {
      client_id,
      client_secret,
      access_token,
      refresh_token,
      refreshTokenExpiresAt,
    });
  } catch (err) {
    throw Error(err);
  }
}

This has nothing to do with Ramda or FP. 这与Ramda或FP无关。 You've got one function doing three different things (auth, token request, and persistence) and that's your problem. 您只有一个函数执行三种不同的操作(身份验证,令牌请求和持久性),这就是您的问题。

const registered = authAPI.registerUser(username, password)
  .catch(err => showUserRegisterErr(err));

const token = registered.then(({client_id, client_secret}) => {
  return Promise.all([
    Promise.resolve({client_id, client_secret}), 
    authAPI.getUserAccessToken(
      username,
      password, 
      client_id, 
      client_secret
    )
  ]);
});

const persisted = token.then((
  {client_id, client_secret},
  {access_token, refresh_token, refreshTokenExpiresAt}
) => {
  return store.update('user', {
    client_id,
    client_secret,
    access_token,
    refresh_token,
    refreshTokenExpiresAt,
  });
});

persisted.catch(err => { throw err; });

Now these are all constant values, not functions, so lets fix that: 现在这些都是常量值,而不是函数,所以让我们修复一下:

// No .catch, caller can catch errors if it wants. Also
// no more registerUser function, it was a thin layer over
// the auth API with error handling and we'll delegate to
// the caller for that.
const getToken = (username, password, registration) => {
  return registration.then(({client_id, client_secret}) => {
    return Promise.all([
      username,
      password,
      client_id,
      client_secret,
      authAPI.getUserAccessToken(
        username,
        password, 
        client_id, 
        client_secret
      )
    ]);
  });
};

const persist = datastore => ([
  client_id,
  client_secret,
  {
    access_token,
    refresh_token,
    refreshTokenExpiresAt
  }
]) => {
  return store.update('user', {
    client_id,
    client_secret,
    access_token,
    refresh_token,
    refreshTokenExpiresAt,
  });
});

const persistToDB = persist(store);
const signUp = (username, password) => {
  return getToken(username, password, authAPI.registerUser(username, password))
    .then(persistToDB)
    .catch(showUserRegistrationErr);
};

Now all the different pieces are independently testable. 现在所有不同的部分都可以独立测试。 Since the registration is passed as a parameter to getToken you can test it with a mock promise. 由于注册是作为getToken的参数传递的,因此您可以使用模拟承诺进行测试。 Likewise with the persistence function. 同样具有持久性功能。 You can also mockout the authAPI.registerUser function. 您也可以模拟authAPI.registerUser函数。

No state is mutated except in the persistence function, functions use only their parameters, etc. I also parameterized the datastore so that you can swap out persistence (or stub it for tests). 除了持久性函数外,没有其他任何状态会发生变化,函数仅使用其参数,等等。我还对数据存储区进行了参数化,以便可以交换持久性(或将其存根进行测试)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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