如何改进我在 nodejs 中的代码?
Posted
技术标签:
【中文标题】如何改进我在 nodejs 中的代码?【英文标题】:How to improve my code in nodejs? 【发布时间】:2016-10-25 17:51:46 【问题描述】:我正在使用 MEAN STACK 应用程序,我想改进我的以下代码。
app.js
var express = require("express");
var router = express.Router();
var Comments = require('../models/Comments');
var Posts = require('../models/Posts');
//use in strict mode
'use strict';
//get user comments and posts
router
.route("/api/user/getUserCommentsAndPosts")
.get(
function(req, res)
/*define variable to run sendResponse() function after completed both comment and post query*/
var commentProcess = 0; //comment process not completed
var postProcess = 0; //post process not completed
/*for store comments and post data in this variable for use in sendResponse() function*/
var commentGlobal;
var postGlobal;
Comments.find( user_id: req.payload.id , function(err, CommentsData)
if (err)
res.json( status: 0, code: 200, type: "error", message: err );
else
commentProcess = 1; //comment process is completed
commentGlobal = CommentsData; //assign local object to global object
sendResponse(); // call this function for send api response
);
Posts.find( user_id: req.payload.id , function(err, PostsData)
if (err)
res.json( status: 0, code: 200, type: "error", message: err );
else
postProcess = 1; //post process not completed
postGlobal = PostsData; //assign local object to global object
sendResponse(); // call this function for send api response
);
//run this function after every process
var sendResponse = function()
// check for all process is completed if completed then send api response
if (commentProcess !== 0 && postProcess !== 0)
var data =comments : commentGlobal, posts : postGlobal;
res.json( status: 1, code: 200, type: "success", data: data );
;
);
我不想在评论和帖子中一步一步地进行查询,因此我不能说最后会完成哪个过程。
如上所述,我必须制作这种类型的代码。
任何机构都可以给我一个改进此代码的指南吗?
谢谢。
【问题讨论】:
你需要这样的东西:npmjs.com/package/bluebird BinariedMe 是正确的。你应该为此使用承诺。有几种不同的 Promise api。 这个问题可能更适合Code Review 网站。 【参考方案1】:您需要某种异步控制库。正如@binariedMe 所说,您可以使用bluebird
,这是一个基于promise 的库,或者您可以使用async
,这是一组具有集中错误处理的不同控制流方法。
【讨论】:
【参考方案2】:当上一次执行的结果被传递到下一次时,这里是使用async waterfall 进行的一些重构
var express = require("express");
var router = express.Router();
var Comments = require('../models/Comments');
var async = require('async');
var Posts = require('../models/Posts');
//use in strict mode
'use strict';
//get user comments and posts
router
.route("/api/user/getUserCommentsAndPosts")
.get(function(req, res)
async.waterfall([
function(callback)
Comments.find( user_id: req.payload.id , function(err, CommentsData)
if (err)
callback(err);
else
var commentProcess = 1; //comment process is completed
var commentGlobal = CommentsData; //assign local object to global object
callback(null, commentProcess, commentGlobal);
);
,
function(commentProcess, commentGlobal, callback)
Posts.find( user_id: req.payload.id , function(err, PostsData)
if (err)
callback(err);
else
var postProcess = 1; //post process not completed
var postGlobal = PostsData; //assign local object to global object
callback(null, commentProcess, commentGlobal, postProcess, postGlobal);
);
], function (err, commentProcess, commentGlobal, postProcess, postGlobal)
if (err)
res.json( status: 0, code: 200, type: "error", message: err );
else
var data =comments : commentGlobal, posts : postGlobal;
res.json( status: 1, code: 200, type: "success", data: data );
);
);
【讨论】:
【参考方案3】:如果您的异步操作很少(2 或 3 个),那么您可以使用 Promise 链接操作系统,当第一次调用成功时,另一个会启动。
如果您有两个以上的异步操作,或者作为更好的做法,您可以使用异步库。 如果您所有的异步操作都是独立的,那么用户 async.parallel。 如果您希望它们按特定顺序执行,则使用 async.waterfall
请查看:https://github.com/caolan/async
【讨论】:
【参考方案4】:这是我的代码版本。它使用 Promise,因此我们可以发出并行请求来获取帖子和 cmets。
const express = require("express");
const router = express.Router();
const Comments = require('../models/Comments');
const Posts = require('../models/Posts');
//use in strict mode
'use strict';
//get user comments and posts
router
.route("/api/user/getUserCommentsAndPosts")
.get(
function (req, res)
const userId = req.payload.id; // use const is better than var
// Do parallel requests using promise.all, it speed up your app indeed
Promise.all([
findCommentsByUserId(userId),
findPostsByUserId(userId)
]).then((comments, posts) =>
res.json(
status: 1,
code: 200,
type: "success",
data: comments, posts
);
)
.catch(err =>
res.json(
status: 0,
code: 200,
type: "error",
message: err
);
);
);
/**
* Find comments by user Id
* - We make this function as promise so we later can do parallel request
* - We move it to function to make your code in router cleaner and easier to read
* @param userId
*/
function findCommentsByUserId(userId)
return new Promise((resolve, reject) =>
Comments.find(
user_id: userId
, function (err, CommentsData)
if (err)
reject(err);
resolve(CommentsData);
);
);
/**
* Find posts by user Id
* We make this function as promise so we can later can do parallel request
* @param userId
*/
function findPostsByUserId(userId)
return new Promise((resolve, reject) =>
Posts.find(
user_id: userId
, function (err, PostsData)
if (err)
reject(err);
resolve(PostsData);
);
);
希望对你有帮助
【讨论】:
以上是关于如何改进我在 nodejs 中的代码?的主要内容,如果未能解决你的问题,请参考以下文章
如何将视频文件作为输入传递给 NodeJS 中的子进程并接收帧/图像作为输出?
如何将媒体文件从服务器流式传输到客户端,例如我在 loopback 4 nodejs 中的 mp3 音频文件?