我有一个函数,可以将大量数据保存在数据库中。回调将在结束时异步调用。
function process(..., fn) {
saveInDB(function(err, results) {
// ...
// fn() or fn(err)
})
}该函数从嵌套循环中多次调用。
for (const x of arrays) {
const space1 = x[0]
for (const y of x.slice(1)) {
const space2 = y[0]
for (const z of y[1]) {
process(space1, space2, z, fn)
}
}
}该问题要求下一次调用仅在上一次成功的情况下发生。这里是我的累赘实现。
let calls = []
for (const x of arrays) {
const space1 = x[0]
for (const y of x.slice(1)) {
const space2 = y[0]
for (const z of y[1]) {
calls.push((fn) => () => process(space1, space2, z, fn))
}
}
}
let call = null
for (let i = calls.length - 1; i >= 0; --i) {
if (i === calls.length - 1) {
call = calls[i](err => {
if (!err)
return finalCallback(null, { 'status': 'success' })
log.error(err)
finalCallback(err)
})
continue
}
const lastNext = call
call = calls[i](err => {
if (!err)
return lastNext()
finalCallback(err)
log.error(err)
})
}
if (call)
call()我正在寻求Javascript专业人士的建议,您是如何解决这类问题的?
发布于 2019-03-21 19:09:30
使用async ... await
在您的用例中,使用await关键字将允许您在继续之前等待process返回的承诺解决。您必须将您的函数定义为async。
您还需要使用try ... catch块来处理任何错误。
由于您的process函数目前没有返回承诺,因此您需要修改它才能这样做。
示例:
function process(/* your args */) {
return new Promise((resolve, reject) => {
saveInDB((err, results) => {
if (err) {
reject(err)
} else {
resolve(results)
}
})
}
// now for the `async ... await`
async function myFunc(arrays) {
for (const x of arrays) {
const space1 = x[0]
for (const y of x.slice(1)) {
const space2 = y[0]
for (const z of y[1]) {
try {
// This will wait until your `process` has finished
await process(space1, space2, z, fn)
} catch (error) {
// handle any errors
console.log(error)
// if you would like to bail after an error you can `return`
return
}
}
}
}
}但是,既然您的函数存在,就可以使用它了,因此它是异步的,因此它不会阻止任何代码在运行之后运行,因此您应该做以下两件事中的一件:
await您的电话到myFunc或saveInDB完成的代码放在.then()中。myFunc(/* your arrays */)
.then(() => {
// your function has finished
})发布于 2019-03-21 19:08:53
saveToDB通常会使用一些表示数据的参数;我只是假设它需要一个数据参数和一个回调,但是可以根据需要进行调整。
首先要证明这一功能。您使用的API可能已经支持承诺,这意味着如果回调函数没有传递给它,上面的函数将返回一个承诺。但是如果不是这样的话,您可以创建自己的promisified:
// promisify the saveInDB function:
const process = (data) => new Promise((resolve, reject) =>
saveInDB(data, (err, results) => err ? reject(error) : resolve(results))
);然后创建一个async函数,以便您可以使用await
async function task(arrays) {
for (const x of arrays) {
const space1 = x[0]
for (const y of x.slice(1)) {
const space2 = y[0]
for (const z of y[1]) {
await process([space1, space2, z])
}
}
}
}..。然后打电话给我。它回报了你的承诺,这样你就可以处理满足和拒绝:
task(arrays).then(() => console.log("all done"))
.catch((err) => console.log("error occurred", err));https://stackoverflow.com/questions/55287288
复制相似问题