我有一个数组,它有一个图像ID,名称和图像本身(base64)。在某些情况下,id会匹配,因此需要使用不同的过程和参数的修订号。但它们必须按顺序运行,以便知道id是否已经存在。
我承诺完成所有这些并且每次都需要调用,但我似乎无法找到最佳方法。网上的一些想法正在使用" reduce"但不确定这是如何运作的。
代码是:
function resetImagesToPouch(image, id, imageName) {
return new Promise(function (resolve, reject) {
var rev;
var imageType;
// check if attachment already exists
DB_TaskImages.get(id, { attachments: true }).then(function (doc) {
rev = doc._rev; // Get the revision number since we are updating and adding attachment to existing doc.
DB_TaskImages.putAttachment(id, imageName, rev, image, "image/jpeg").then(function () {
console.log("Attachment added successfully");
return;
}).then(function () {
resolve();
}).catch(function (err) {
reject(err);
});
return;
}).catch(function (err) {
if (err.status = '404') { // if this is a new document - add new attachment
//imageType = GetImageTypeFromBase64(image);
DB_TaskImages.putAttachment(id, imageName, image, "image/jpeg").then(function () {
console.log("Attachment added successfully");
return;
}).then(function () {
resolve();
}).catch(function (err) {
reject(err);
})
}
});
}); // end promise
}
我需要刷新表格所需的图像数组,例如:
images = {
{id = "111", imageName='fighter.jpg', image='aaaaaddddd'},
{id = "111", imageName='horse.jpg', image='aaasdfssdaaddddd'},
{id = "112", imageName='cat.jpg', image='aasdfaaadsdfsfdddd'},
{id = "113", imageName='dog.jpg', image='aaasdfasfaaaddddd'},
{id = "1234", imageName='apple.jpg', image='aaaasdfasaaddddd'}
}
我不知道数组中有多少或数值是多少。我该怎么做?我不能使用Promise.all(我不这么认为),因为他们不能一起开火,但.get和.put是异步的,我需要每个承诺完成。我不能使用那些因为我不知道会有多少人。
由于
下面的答案很好,除了它是链的一部分并在完成之前退出代码。
}).then(function () {
return ajaxCallForJsonTwoResults(URI_WorkIssues);
}).then(function (args) {
args[1].reduce(function (promise, image) {
return promise.then(function () {
return resetImagesToPouch(image);
});
}, Promise.resolve(args)).then(function () {
console.log('all done with images');
});
}).then(function (args) {
return callBulkDocLoad(DB_WorkIssues, args[0]);
}).then(function () {
在代码中,我传递了args(其中有两个数组 - args [0]和args [1])。我在这里处理两个数据库所以我需要两个回复。问题是当我从我的ajax调用回来时,我使用args [1]作为第一个promise,而args [0]作为另一个。但是,由于我过早地从第一个承诺中回来,并且尚未达到将args传递给callBulkDocLoad函数的决心,因此未定义。
我错过了什么吗?
感谢。
它几乎可以工作。
返回确实使循环在跳出之前完成了reduce循环但是它没有执行resetImagesToPouch调用,直到完成所有循环并且只执行一次。
var argsSaved;
...
// WorkIssues
}).then(function () {
if (DB_WorkIssues != null)
return DB_WorkIssues.erase();
}).then(function () {
return DB_WorkIssues = new PouchDB(DBNAME_WorkIssues, { auto_compaction: true });
}).then(function () {
return ajaxCallForJsonTwoResults(URI_WorkIssues);
}).then(function (args) {
argsSaved = args;
return args[1].reduce(function (promise, image) {
return promise.then(function () {
return resetImagesToPouch(image);
});
}, Promise.resolve(args)).then(function () {
console.log('all done with images');
});
}).then(function (args) {
return callBulkDocLoad(DB_WorkIssues, argsSaved[0]);
}).then(function () {
updateWorkIssuesJson();
loadTaskList(false);
这是resetImagesToPouch功能:
var resetImagesToPouch = function resetImagesToPouch(_ref) {
var image = _ref.AttachmentFile,
id = _ref.JobNumber,
imageName = _ref.DocTitle;
return DB_TaskImages.get(id, {
attachments: true
}).then(function (doc) {
return DB_TaskImages.putAttachment(id, imageName, doc._rev, image, 'image/jpeg');
}).catch(function (err) {
if (err.status = '404') {
// if this is a new document - add new attachment
//var imageType = GetImageTypeFromBase64(image);
return DB_TaskImages.putAttachment(id, imageName, image, 'image/jpeg');
} else {
throw err;
}
});
};
在返回之前,循环只发生一次然后跳出来。有六个图像,循环现在发生了几次,但在完成所有循环之前不会执行resetImagesToPouch。
所以它是这样的:首先是减少,然后是#34;返回promise.then"和Promise.Resolve六次,然后它跳到"然后"然后它跳回到resetImagesToPouch,在那里它执行DB_TaskImages.get以查看这是否是此id的第一个图像,并且由于数据库为空,它将转到catch和404内部,如果是statment,然后是DB_TaskImages.putAttachment它跳转到函数末尾的位置,然后跳转到链末尾的catch,并显示错误:
err = r {status:404,name:" not_found",message:" missing",error:true,reason:" deleted"}
这是我们从.get通话中得到的错误,它给了我们404(我相信),所以我不知道它为什么会去那里。这似乎不是你从put得到的错误。所以它永远不会在链的最后一部分,因为它跳过它并且表中没有放置图像记录。
感谢。
在指出我错过了一个" =="之后,我更改了resetImagesToPouch()并修复了它,并添加了thens和catches to puts。这似乎解决了没有完成链条的问题。
var resetImagesToPouch = function resetImagesToPouch(_ref) {
var image = _ref.AttachmentFile,
id = _ref.JobNumber,
imageName = _ref.DocTitle;
return DB_TaskImages.get(id, {
attachments: true
}).then(function (doc) {
DB_TaskImages.putAttachment(id, imageName, doc._rev, image, 'image/jpeg').then(function () {
console.log("Success insert of multiple attachment");
return;
}).catch(function () {
console.log("Error in resetImagesToPouch: " + err);
showMsg("Error in resetImagesToPouch: " + err);
})
}).catch(function (err) {
if (err.status == '404') {
// if this is a new document - add new attachment
//var imageType = GetImageTypeFromBase64(image);
DB_TaskImages.putAttachment(id, imageName, image, 'image/jpeg').then(function () {
console.log("Successfull insert of multiple attachment");
return;
}).catch(function () {
console.log("Error in resetImagesToPouch: " + err);
showMsg("Error in resetImagesToPouch: " + err);
});
} else {
console.log("At throw error");
throw err;
}
});
};
但它仍然没有插入任何图像。参数看起来很好,但是总是需要使用"未找到"以及上面的404错误。和"删除"。我能想到的唯一一件事(但不确定为什么会出现这种情况)是我在执行这些部分之前对这个数据库进行擦除(就像我对所有数据库所做的那样)。
// TaskImages
}).then(function () {
if (DB_TaskImages != null)
return DB_TaskImages.erase();
}).then(function () {
return DB_TaskImages = new PouchDB(DBNAME_TaskImages, { auto_compaction: true });
我为大约6个数据库执行此操作,因为我正在从服务器重新加载它们。我想知道循环中的.gets和.put是否可能导致问题?似乎没有多大意义。
我只是尝试了一些新的擦除并将其更改为销毁。这效果更好。与从不添加任何图像的擦除不同,这个将添加6个图像中的4个。它在其中两个中得到404错误,但不是说理由:"删除",它说原因:"缺少"。我认为这个问题是这些实际上是同一个ID的多个附件。但由于某些原因,当.get完成时,它没有找到记录,所以它做了一个没有修订的.put(采用了404路径)并在此时找到了记录并因为修订而给出了错误失踪。也许,当它第一次录制时,当第二张唱片出现时它还没有完成。
感谢。
我今天早些时候重新设计了resetImagesToPouch,因为我无法让旧版本工作。它总是起作用,但总有一些东西没有,而且我的时间已经不多了。擦除和丢失图像导致的404错误是一个问题。
我最终回到我的resetImagesToPouch是一个承诺,并且终于能够让它在没有跳跃的情况下工作,并且出于某种原因没有图像问题,只要我做了破坏而不是擦除。擦除不会保存任何东西。它刚刚回来了404失踪或404删除。我只是没时间试图找出原因。
以下是我今天下午终于完成的工作。
// TaskImages
}).then(function () {
if (DB_TaskImages != null)
return DB_TaskImages.destroy();
}).then(function () {
return DB_TaskImages = new PouchDB(DBNAME_TaskImages, { auto_compaction: true });
// WorkIssues
}).then(function () {
if (DB_WorkIssues != null)
return DB_WorkIssues.erase();
}).then(function () {
return DB_WorkIssues = new PouchDB(DBNAME_WorkIssues, { auto_compaction: true });
}).then(function () {
return ajaxCallForJsonTwoResults(URI_WorkIssues);
}).then(function (args) {
argsSaved = args;
console.log("Before the reduce");
return args[1].reduce(function (promise, image) {
console.log("After the reduce and before the promise.then");
return promise.then(function () {
console.log("Inside the promise.then and before the resetImagesToPouch");
return resetImagesToPouch(image).then(function () {
console.log('Image written to Pouch successfully');
}).catch(function (err) {
console.log("Error in resetImagesToPouch with err: " + err);
});
console.log("After the resetImagesToPouch");
});
console.log("Before the Promise.resolve");
}, Promise.resolve(args)).then(function () {
console.log('all done with images');
});
}).then(function (args) {
console.log("Before the callBulkDocLoad");
if (argsSaved[2].length > 0) {
console.log("Ajax issue with err: " + argsSaved[2][0]);
msg = "Ajax issue with err: " + argsSaved[2][0];
}
return callBulkDocLoad(DB_WorkIssues, argsSaved[0]);
}).then(function () {
console.log("Before the updateWorkIssuesJson");
updateWorkIssuesJson();
loadTaskList(false);
还有resetImagesToPouch:
function resetImagesToPouch(_ref) {
var image = _ref.AttachmentFile,
id = _ref.JobNumber,
imageName = _ref.DocTitle;
return new Promise(function (resolve, reject) {
var rev;
var imageType;
// check if attachment already exists
DB_TaskImages.get(id, { attachments: true }).then(function (doc) {
rev = doc._rev; // Get the revision number since we are updating and adding attachment to existing doc.
DB_TaskImages.putAttachment(id, imageName, rev, image, "image/jpeg").then(function () {
console.log("Attachment added successfully");
return;
}).then(function () {
resolve();
}).catch(function (err) {
reject(err);
});
return;
}).catch(function (err) {
if (err.status = '404') { // if this is a new document - add new attachment
//imageType = GetImageTypeFromBase64(image);
DB_TaskImages.putAttachment(id, imageName, image, "image/jpeg").then(function () {
console.log("Attachment added successfully");
return;
}).then(function () {
resolve();
}).catch(function (err) {
reject(err);
})
}
});
}); // end promise
}
它可能不是处理它的最佳方式,但它正在发挥作用。我现在对它的理解比较好,但仍然需要用它来处理我不喜欢的部分。比如在reduce中的部分,我还没有真正了解所有这些,并且当我有更多时间时会看到它。我确实得到了一些。但不确定为什么它会在所有resetImagesToPouch调用之前在所有图像的promise.then和Promise.resolve之间来回反弹。当我出城去复活节时,这将给我一些工作。
感谢所有帮助。
我怀疑没有它我会得到它。
答案 0 :(得分:1)
使用array.reduce很简单,一旦你有一个有效的数组
let images = [
{ id: '111', imageName: 'fighter.jpg', image: 'aaaaaddddd' },
{ id: '111', imageName: 'horse.jpg', image: 'aaasdfssdaaddddd' },
{ id: '112', imageName: 'cat.jpg', image: 'aasdfaaadsdfsfdddd' },
{ id: '113', imageName: 'dog.jpg', image: 'aaasdfasfaaaddddd' },
{ id: '1234', imageName: 'apple.jpg', image: 'aaaasdfasaaddddd' }
]
重写resetImagesToPouch
以正确返回承诺
let resetImagesToPouch = ({image, id, imageName}) =>
DB_TaskImages.get(id, {
attachments: true
})
.then((doc) => DB_TaskImages.putAttachment(id, imageName, doc._rev, image, 'image/jpeg'))
.catch ((err) => {
if (err.status = '404') { // if this is a new document - add new attachment
//var imageType = GetImageTypeFromBase64(image);
return DB_TaskImages.putAttachment(id, imageName, image, 'image/jpeg');
} else {
throw err;
}
});
现在,你要减少它的魔力
images.reduce((promise, image) => promise.then(() => resetImagesToPouch(image)), Promise.resolve())
.then(() => {
console.log('all done');
});
如果ES2015 +吓到你了
var resetImagesToPouch = function resetImagesToPouch(_ref) {
var image = _ref.image,
id = _ref.id,
imageName = _ref.imageName;
return DB_TaskImages.get(id, {
attachments: true
}).then(function (doc) {
return DB_TaskImages.putAttachment(id, imageName, doc._rev, image, 'image/jpeg');
}).catch(function (err) {
if (err.status = '404') {
// if this is a new document - add new attachment
//var imageType = GetImageTypeFromBase64(image);
return DB_TaskImages.putAttachment(id, imageName, image, 'image/jpeg');
} else {
throw err;
}
});
};
现在,你要减少它的魔力
images.reduce(function (promise, image) {
return promise.then(function () {
return resetImagesToPouch(image);
});
}, Promise.resolve()).then(function () {
console.log('all done');
});
看着"链"在编辑过的问题中
}).then(function () {
return ajaxCallForJsonTwoResults(URI_WorkIssues);
}).then(function (args) {
// add return here
return args[1].reduce(function (promise, image) {
return promise.then(function () {
return resetImagesToPouch(image);
});
}, Promise.resolve(args))
.then(function () {
console.log('all done with images');
// pass on args down the chain
return args;
});
}).then(function (args) {
return callBulkDocLoad(DB_WorkIssues, args[0]);
}).then(function () {
并且为了完整起见 - 在ES2015 +中
})
.then(() => ajaxCallForJsonTwoResults(URI_WorkIssues))
.then(([docs, images]) =>
images
.reduce((promise, image) =>
promise.then(() =>
resetImagesToPouch(image)),
Promise.resolve()
)
.then(() => docs)
)
.then(docs => callBulkDocLoad(DB_WorkIssues, docs))
.then(() => {