如何在页面加载中使用Javascript成功完成Ajax请求

我正在购物车应用程序上工作。 用户将添加项目到他们的“购物车”,这是存储在本地存储。 当用户导航到他们将商品添加到购物车的不同页面时,页面需要填充他们添加到购物车的商品(本地存储)。 我正在使用handlebars为我的页面构build模板,NodeJS / ExpressJS为get / post请求创build路由和填充页面,Ajax向客户端和服务器发送请求。

目前,当用户访问视图购物车页面,我第一次通过工作,但是,我得到一个'错误:发送后无法设置标题。 这也正在以相当糟糕的方式完成。

首先,这里是我的视图购物车页面的初始获取代码:

viewCart: function(req, res){ if(req.session.success){ res.render('base', {title: 'View Cart', userNav: true, checkoutNav: true, viewCart: true, cartIcon: true, js:js}); }else{ res.render('base', {title: 'View Cart', userNav: true, viewCart: true, cartIcon: true, js:js}); } }, 

这只是渲染页面中没有来自本地存储的数据。 这里是我要调用的variables的html,用本地存储中的数据填充:

  <div id="viewCartTable"></div> 

在我的JavaScript中,我有这个function,当id“viewCartTable”在那里,并执行一个ajax请求:

 if(document.getElementById("viewCartTable")){ var data = localStorage.getItem("Products"); Ajax.sendRequest("/user/viewCart", function(res){ responseArr = res.responseText.split('^^^'); if(responseArr[0] === "error"){ console.log("error"); setTimeout(function(){('','#000',false)}, 1500); }else if(responseArr[0] === "Success"){ console.log("Success"); var tableCart = document.getElementById("viewCartTable"); tableCart = tableCart.innerHTML = responseArr[1]; }}, data); } 

这个Ajax请求被发送到查看购物车页面的post,我相信这可能是问题真正展开的地方。 他是这个职位:

 viewCartPost: function(req, res){ var data = JSON.parse(req.body.data); console.log(data); var keys = Object.keys(data); //console.log(keys); for(var i = 0; i<keys.length; i++){ var productId = keys[i]; Product.find({productId: productId}).select({productId : 1, addProductGroupName: 1, productName: 1, productPrice: 1, productDescription: 1, filePath: 1}).exec(function(err, cartProducts){ if(err){ console.log(err); res.send("error"); }else{ res.send("Success^^^"+cartProducts); } }); console.log(productId); } }, 

这是获取从客户端发送的本地存储信息,并查找与在本地存储中存储和发送的productId相匹配的产品及其信息。

所以这个目前的设置是第一次通过。 对页面的初始访问将产品的数据打印在本地存储器中,并将“成功”发送到前端。 但是,在设置完毕后,立即在Cant set标题之后给出。 我相信这是因为当我find“viewCartTable”的ID我发送一个Ajax请求。 因此,必须有更好的方法来触发ajax请求,并将数据发送到服务器并从服务器发回客户端。

有没有更好的方法来使这个Ajax请求获得所需的数据? 到目前为止,加载和加载都失败了。 任何帮助表示赞赏。 谢谢。

第2部分

遍历数据并以表格格式打印。 所以在服务器端我正在使用这个函数的结果:

 viewCartPost: function(req, res){ var data = JSON.parse(req.body.data); console.log(data); var keys = Object.keys(data); //console.log(keys); var promises = []; for(var i = 0; i<keys.length; i++){ var productId = keys[i]; promises.push(Product.find({productId: productId}).select({productId : 1, addProductGroupName: 1, productName: 1, productPrice: 1, productDescription: 1, filePath: 1}).exec()); } Promise.all(promises).then(function(results) { // you may have to reorganize results to be exactly what you want // to return to the client var cartTable = viewCartTable(results); res.send("Success^^^"+cartTable); }).catch(function(err){ res.sendStatus(500); }); }, 

并将其发送到一个函数,该函数正在构build此函数的结果表:

 function viewCartTable(results){ console.log(results[0]); } 

现在这个函数只是看第一个结果。 哪一个是1特定产品的整个数据集。 看起来像这样:

 [ { _id: 583df3eead025434e61a2172, filePath: '/public/images/df54528a827f99586135956e45f045fe.jpg', addProductGroupName: 'Xbox One', productName: 'Far Cry', productPrice: 78.34, productDescription: 'Its back again. I have never played this game but heard it is pretty good. Wanted to write an extra long description to see if someone really took the time to type such a longer sentence how exactly it would appear on things throughout the application.', productId: 'rJUg4uiGl' } ] 

在我build立这样一个表的所有其他实例中,我已经能够调用results [0] .productId来获得结果的具体productId。 在这里,它返回一个未定义的。 所有其他尝试也返回一个未定义的。 任何想法如何轻松地遍历每个这样的数据集? 我觉得我是愚蠢的这个想法,我不知道这个:(

这个服务器代码是错误的:

 viewCartPost: function(req, res){ var data = JSON.parse(req.body.data); console.log(data); var keys = Object.keys(data); //console.log(keys); for(var i = 0; i<keys.length; i++){ var productId = keys[i]; Product.find({productId: productId}).select({productId : 1, addProductGroupName: 1, productName: 1, productPrice: 1, productDescription: 1, filePath: 1}).exec(function(err, cartProducts){ if(err){ console.log(err); res.send("error"); }else{ res.send("Success^^^"+cartProducts); } }); console.log(productId); } }, 

你有res.send("Success^^^"+cartProducts);for循环中。 这意味着你多次调用它。 这意味着你正试图发送多个响应这个请求,并触发你看到的错误。 这是错误的服务器代码。 您只需要针对任何给定的请求发送一个响应。

在我能build议什么代码能最好地解决这个问题之前,我将不得不了解所需的单一响应。 如果你打算执行这样的多个asynchronous操作,并且你想知道什么时候所有这些都完成了,那么你必须编写代码来跟踪它们,并在它们完成时得到通知,然后发送一个且只有一个响应。

这可以用一个计数器和一些代码来增加和检查计数器,也可以通过切换使用promise来跟踪你的asynchronous操作,并使用Promise.all()来通知你什么时候所有的asynchronous操作都完成了。

当你在这个function中有多个键时,发送的单个响应是什么?


我自己也不太了解mongoose,但是在最新版本的.exec().exec()返回一个promise,以便我们可以使用它来协调多个asynchronous数据库操作,如下所示:

 viewCartPost: function(req, res){ var data = JSON.parse(req.body.data); console.log(data); var keys = Object.keys(data); //console.log(keys); var promises = []; for(var i = 0; i<keys.length; i++){ var productId = keys[i]; promises.push(Product.find({productId: productId}).select({productId : 1, addProductGroupName: 1, productName: 1, productPrice: 1, productDescription: 1, filePath: 1}).exec()); } Promise.all(promises).then(function(results) { // you may have to reorganize results to be exactly what you want // to return to the client res.json(results); }).catch(function(err){ console.error("viewCartPost", err); res.sendStatus(500); }); },