Javascript 函数在.then()承诺之前执行
目标:如果html元素的数量超过现有JSON文件的数组,则在JSON中创建数组。然后,获取每个数组的Javascript 函数在.then()承诺之前执行,javascript,jquery,arrays,json,Javascript,Jquery,Arrays,Json,目标:如果html元素的数量超过现有JSON文件的数组,则在JSON中创建数组。然后,获取每个数组的.length,并添加到将附加到html的btn 我有一个脚本,它首先检测页面上有多少postWrapper元素,然后循环遍历它们,确定注释,是否喜欢和视图(三个存储三个外部JSON文件的变量)对于每个索引的postWrapper元素,它们都有相应的数组。如果其中一个JSON文件中不存在数组,则postArray()函数将进行$.ajax调用,php将在每个JSON文件的末尾写入一个空数组。然后,
.length
,并添加到将附加到html的btn
我有一个脚本,它首先检测页面上有多少postWrapper
元素,然后循环遍历它们,确定注释
,是否喜欢
和视图
(三个存储三个外部JSON文件的变量)对于每个索引的postWrapper
元素,它们都有相应的数组。如果其中一个JSON文件中不存在数组,则postArray()
函数将进行$.ajax
调用,php将在每个JSON文件的末尾写入一个空数组。然后,您将看到我使用.push([])
向现有的注释添加一个空数组,喜欢和视图变量,以便它们也反映更新的JSON文件
我正在使用.then()
来确保这些函数中的一些是同步执行的。更新JSON文件并将空数组推送到现有js变量后,我需要借助我的injectBtn()
函数将按钮附加到postWrapper
元素。此函数读取注释
、喜欢
和视图
变量,以确定数组的长度
,然后添加计数(如果愿意)
我面临的问题是,如果这三个JSON文件中的一个没有足够数量的数组,那么postArray()
函数似乎会成功执行(因此JSON文件会被更新),但是获得.push([])
方法的js变量在injectBtn()之前不会更新
尝试执行并获取新创建数组的.length
。然后,我将出现以下错误:
延迟异常:无法读取未定义类型的属性“includes”错误:无法读取未定义类型的属性“includes”
如何解决此问题,以便在injectBtn()
尝试读取其中包含的数组的.length
之前,更新我的JSON文件和注释
、类
和视图
变量
我的代码如下(至少我认为相关的部分)。请让我知道,如果你有任何问题或需要任何更多的背景
var postArray = function() {
return $.ajax({
type: "post",
url: "/php/api.php",
dataType: "text",
data: {
array: "new"
}
});
}
var injectBtns = function(element, index) {
$(element[index]).append(
"<a class='js comment btn' href='#' title='Comment'>" +
"<span class='js comment count'>" + comments[index].length + "</span>" +
"<svg class='icon' width='16px' height='16px' viewbox='0 0 16 16'>" +
"<use xlink:href='/assets/icons.svg#comments'></use>" +
"</svg>" +
"</a>" +
"<a class='js like btn' href='#' title='Like'>" +
"<span class='js like count'>" + likes[index].length + "</span>" +
"<svg class='icon' width='16px' height='16px' viewbox='0 0 16 16'>" +
"<use xlink:href='/assets/icons.svg#likes'></use>" +
"</svg>" +
"</a>" +
"<a class='js view btn' href='#' title='Like'>" +
"<span class='js view count'>" + views[index].length + "</span>" +
"<svg class='icon' width='16px' height='16px' viewbox='0 0 16 16'>" +
"<use xlink:href='/assets/icons.svg#views'></use>" +
"</svg>" +
"</a>"
);
}
var postWrapper = $(".js.post.wrapper"),
commentBtn = ".js.comment.btn",
likeBtn = ".js.like.btn",
viewBtn = ".js.view.btn";
for (var i = 0; i < $(postWrapper).length; i++) {
(function(index) {
if (typeof comments[index] === "undefined" || typeof likes[index] === "undefined" || typeof views[index] === "undefined") {
postArray().then(function() {
comments.push([]);
likes.push([]);
views.push([]);
injectBtns(postWrapper, index);
});
} else {
injectBtns(postWrapper, index);
}
})(i);
if (comments[i].includes(client)) {
$(postWrapper[i]).children(commentBtn).addClass("active");
}
if (likes[i].includes(client)) {
$(postWrapper[i]).children(likeBtn).addClass("active");
$(postWrapper[i]).children(likeBtn).prop("title", "Unlike");
}
if (views[i].includes(client)) {
$(postWrapper[i]).children(viewBtn).addClass("active");
}
}
var postArray=function(){
返回$.ajax({
类型:“post”,
url:“/php/api.php”,
数据类型:“文本”,
数据:{
数组:“新”
}
});
}
var injectBtns=函数(元素、索引){
$(元素[索引])。追加(
"" +
"" +
""
);
}
var postWrapper=$(“.js.post.wrapper”),
commentBtn=“.js.comment.btn”,
likeBtn=“.js.like.btn”,
viewBtn=“.js.view.btn”;
对于(var i=0;i<$(postWrapper).length;i++){
(功能(索引){
if(评论类型[索引]==“未定义”| |喜欢类型[索引]==“未定义”| |视图类型[索引]==“未定义”){
postArray().then(函数(){
注释。推送([]);
喜欢。推([]);
视图。推送([]);
InjectBTN(postWrapper,索引);
});
}否则{
InjectBTN(postWrapper,索引);
}
})(i) );
if(注释[i]。包括(客户)){
$(postWrapper[i]).children(commentBtn).addClass(“活动”);
}
如果(喜欢[i]。包括(客户)){
$(postWrapper[i]).children(likeBtn).addClass(“活动”);
$(postWrapper[i])。children(likeBtn).prop(“title”,“nother”);
}
if(视图[i]。包括(客户端)){
$(postWrapper[i]).children(viewBtn).addClass(“活动”);
}
}
如何解决这个问题,以便在injectBtn()尝试读取其中包含的数组的.length之前更新JSON文件和注释、likes和views变量
您需要将它们放在中,然后也放在回调中
for (var i = 0; i < $(postWrapper).length; i++) {
(function(i) {
var promise = (typeof comments[i] === "undefined" || typeof likes[i] === "undefined" || typeof views[i] === "undefined")
? postArray().then(function() {
comments.push([]);
likes.push([]);
views.push([]);
})
: $.when(undefined);
promise.then(function() {
injectBtns(postWrapper, i);
if (comments[i].includes(client)) {
$(postWrapper[i]).children(commentBtn).addClass("active");
}
if (likes[i].includes(client)) {
$(postWrapper[i]).children(likeBtn).addClass("active");
$(postWrapper[i]).children(likeBtn).prop("title", "Unlike");
}
if (views[i].includes(client)) {
$(postWrapper[i]).children(viewBtn).addClass("active");
}
});
})(i);
}
for(var i=0;i<$(postWrapper).length;i++){
(职能(一){
var promise=(评论类型[i]=“未定义”| |喜欢类型[i]=“未定义”| |视图类型[i]=“未定义”)
?postArray()。然后(函数(){
注释。推送([]);
喜欢。推([]);
视图。推送([]);
})
:$.when(未定义);
promise.then(函数(){
injectBtns(postWrapper,i);
if(注释[i]。包括(客户)){
$(postWrapper[i]).children(commentBtn).addClass(“活动”);
}
如果(喜欢[i]。包括(客户)){
$(postWrapper[i]).children(likeBtn).addClass(“活动”);
$(postWrapper[i])。children(likeBtn).prop(“title”,“nother”);
}
if(视图[i]。包括(客户端)){
$(postWrapper[i]).children(viewBtn).addClass(“活动”);
}
});
})(i) );
}
注意,整个方法非常可怕
- 为了防止竞争条件,您不应该仅仅请求“创建一个新数组(在末尾)”,而是“在
i
位置创建一个数组(如果它还不存在)”
- 您不应该发出多个请求(每个缺少的数组一个请求),而应该发出一个具有预期数组数的简单请求(即
postWrapper.length
)。然后,php脚本应根据需要生成尽可能多的内容
- 您根本不应该为此使用客户端脚本,甚至不应该接受请求来创建单独的评论/类似/查看部分(这是一个巨大的安全风险)。php服务器应该知道有多少帖子