Javascript 正在努力使用Ramda.js重构它,下面是我所取得的进展

Javascript 正在努力使用Ramda.js重构它,下面是我所取得的进展,javascript,functional-programming,ramda.js,Javascript,Functional Programming,Ramda.js,我正在学习Ramda.js。下面是我试图用Ramda重构的函数。它调用函数firestore数据库方法来获取一些数据。但是firestore在快照方法中返回数据,我们需要调用.data()。根据结果,我想构造不同的响应 很乐意在这里介绍您的思考过程 const queryForUsersQuizResults = async (request, response) => { try { const snapshot = await firestore .collec

我正在学习Ramda.js。下面是我试图用Ramda重构的函数。它调用函数
firestore
数据库方法来获取一些数据。但是firestore在
快照
方法中返回数据,我们需要调用
.data()
。根据结果,我想构造不同的响应

很乐意在这里介绍您的思考过程

const queryForUsersQuizResults = async (request, response) => {
  try {
    const snapshot = await firestore
      .collection("quizResults")
      .doc(request.user.uid)
      .collection("courses_chapters")
      .doc(request.params.courseId + "_" + request.params.chapterId)
      .get();

    let data = snapshot.data();
    if (!data) {
      data = {
        message: "result not found for this user for this course and chapter"
      };
    }

    return response.send(data);
  } catch (error) {
    return response.status(500).send(error);
  }
}
…下面是我能够重构的东西,我希望看到更好的/其他的方法(我不确定这是否有效)。我正在努力使用
sendResult
方法

//get user id
export const getUserId = pathOr('', ['user', 'uid']);

// get chapter id
export const getChapterId = concat(pathOr('', ['params', 'courseId']), '_', pathOr('', ['params', 'chapterId']));

//queryQuizResult
export const query = curry(async (firestore, request) => {
  return tryCatch(() =>
    firestore
    .collection("quizResults")
    .doc(getUserId(request))
    .collection("courses_chapters")
    .doc(getChapterId(request))
    .get(), F)();
});

//Receives "response" object and calls response.status with the value passed to the new status function
export const status = invoker(1, "status");

//Receives "response" object and calls response.send witht he value passed to the new send function
export const send = invoker(1, "send");

//Create {"message",Your_Error} object
export const constructError = objOf('message');

//Returns JSON from Firestore's snapshot object
export const getDataFromSnapshot = (snapshot) => snapshot.data();

//Actual error message
const QUIZ_RESULTS_NOT_FOUND = "Quiz results not found for this user for this course and chapter";

//Returns error message
export const quizResultsNotFoundError = constructError(QUIZ_RESULTS_NOT_FOUND);

//Receives "response" object and calls response.status and then respose.send
export const sendError = pipe(
  status(401),
  send(quizResultsNotFoundError)
);
//Sends valid result  //IS there any better way of doing this?
export const sendResult = (snapshot, response) => {
  const data = getDataFromSnapshot(snapshot);
  response.send(data); //Especially this, I wanted to use the "send" method and pipe things
}

//Main Method
export const  queryForUsersQuizResults = async (firestore, request, response) => {
 const snapshot = await query(firestore, request);
 snapshot ? sendResult(snapshot, response) :sendError(response);
}

我还认为你已经拥有的是好的,如果你真的想使用构图,它可以是这样的:

export const sendResult = (snapshot, response) =>
  pipe(getDataFromSnapshot, flip(send)(response))
    (snapshot);

您需要使用
flip
,因为(在管道定义时)还没有
getDataFromSnapshot(snapshot)
的结果,但是您已经有了包含
send
方法实现的对象。

下面是我看到的移动部分。这只是编写程序的许多可能方法之一。我们将从firestore请求的
数据
的通用帮助程序开始-

//get user id
export const getUserId = pathOr('', ['user', 'uid']);

// get chapter id
export const getChapterId = concat(pathOr('', ['params', 'courseId']), '_', pathOr('', ['params', 'chapterId']));

//queryQuizResult
export const query = curry(async (firestore, request) => {
  return tryCatch(() =>
    firestore
    .collection("quizResults")
    .doc(getUserId(request))
    .collection("courses_chapters")
    .doc(getChapterId(request))
    .get(), F)();
});

//Receives "response" object and calls response.status with the value passed to the new status function
export const status = invoker(1, "status");

//Receives "response" object and calls response.send witht he value passed to the new send function
export const send = invoker(1, "send");

//Create {"message",Your_Error} object
export const constructError = objOf('message');

//Returns JSON from Firestore's snapshot object
export const getDataFromSnapshot = (snapshot) => snapshot.data();

//Actual error message
const QUIZ_RESULTS_NOT_FOUND = "Quiz results not found for this user for this course and chapter";

//Returns error message
export const quizResultsNotFoundError = constructError(QUIZ_RESULTS_NOT_FOUND);

//Receives "response" object and calls response.status and then respose.send
export const sendError = pipe(
  status(401),
  send(quizResultsNotFoundError)
);
//Sends valid result  //IS there any better way of doing this?
export const sendResult = (snapshot, response) => {
  const data = getDataFromSnapshot(snapshot);
  response.send(data); //Especially this, I wanted to use the "send" method and pipe things
}

//Main Method
export const  queryForUsersQuizResults = async (firestore, request, response) => {
 const snapshot = await query(firestore, request);
 snapshot ? sendResult(snapshot, response) :sendError(response);
}
const getData=doc=>
文件存在
? 文件数据()
:承诺。拒绝(错误(“未找到”))
我们现在可以为UserSquizResults编写一个
查询,但我们会小心地将它与路由处理程序
请求
响应
-

constqueryforusersquizresults=(uid,docid)=>
火库
.collection(“quizResults”)
.doc(uid)
.收藏(“课程和章节”)
.doc(docid)
.get()
.然后(getData)//
queryForUsersQuizResults
(req.user.uid)
,req.params.courseId+“”+req.params.chapterId
)
.那么
(手动成功(res)
,handleError(404)(res)
)
这取决于可以链接到任何承诺的通用处理程序
handleSuccess
handleError
-

const handleSuccess=res=>data=>
资源发送(数据)
const handleError=code=>res=>err=>
资源状态(代码).发送(错误消息)
演示

这里有一个工作演示来展示实际的概念。 由于stacksnippets中没有可用的数据库、
firestore
express
,因此我们必须模拟它们-

const DB=
{1:“蚂蚁”
,2:“熊”
,3:“乌贼”
}
const fakeFirestore=id=>
新承诺
(r=>
DB[id]==未定义
?r({exists:false})
:r({exists:true,data:()=>DB[id]})
)
const fakeResponse=(状态=200)=>
({发送:数据=>
console.log(“=>”,状态,数据)
,状态:n=>
虚假回应(n)
})
我们将测试对每个数据库记录和一个不存在的记录的查询-

myRoute
({params:{uid:1}}
,fakeResponse()
)
我的路线
({params:{uid:2}}
,fakeResponse()
)
我的路线
({params:{uid:3}
,fakeResponse()
)
我的路线
({params:{uid:4}
,fakeResponse()
)
展开下面的代码段,在您自己的浏览器中验证结果-

const getData=doc=>
文件存在
? 文件数据()
:承诺。拒绝(错误(“未找到”))
const handleSuccess=res=>data=>
资源发送(数据)
const handleError=code=>res=>err=>
资源状态(代码).发送(错误消息)
const fakeResponse=(状态=200)=>
({发送:数据=>
console.log(“=>”,状态,数据)
,状态:n=>
虚假回应(n)
})
const fakeFirestore=id=>
新承诺
(r=>
DB[id]==未定义
?r({exists:false})
:r({exists:true,data:()=>DB[id]})
)
const queryForUsersQuizResults=(id=0)=>
假货商店(id)
.then(获取数据)
常量myRoute=(请求、恢复)=>
queryForUsersQuizResults(请求参数uid)
.那么
(手动成功(res)
,handleError(404)(res)
)
常数分贝=
{1:“蚂蚁”
,2:“熊”
,3:“乌贼”
}
我的路线
({params:{uid:1}}
,fakeResponse()
)/=>200蚂蚁
我的路线
({params:{uid:2}}
,fakeResponse()
)/=>200熊
我的路线
({params:{uid:3}
,fakeResponse()
)//=>200条墨鱼
我的路线
({params:{uid:4}
,fakeResponse()

)//=>404未找到
第一个版本有什么问题?我的意思是,我会将数据库检查转移到一个单独的函数中,但您似乎在增加很多复杂度,但收获甚微。我的项目中有许多类似的函数,所以我正在以FP样式重构它们,以便可以重复使用。我认为我剩下的大部分函数都只是几行代码。我一直在使用Ramda,但这里没有做任何数据处理,只是将数据从数据库传输到前端。这很好,但很简单,应该保持简单。如果你想找出常见的东西,只需要用返回处理程序的通用逻辑创建一个HOF。或者做一个装饰师。请注意,我们不必再接触异步
/
等待
了-将重型机械用于最艰巨的工作