异步操作完成后如何从节点脚本退出?

时间:2018-12-29 17:01:52

标签: javascript node.js

我正在尝试运行循环并在其中执行异步操作。我正在尝试从Mongodb删除文档。我希望脚本在所有删除操作完成后终止。我尝试使用process.exit(0),但是当我使用此方法终止脚本时,没有数字被删除。

async function deletor() {
mobile_numbers.forEach(async (mobile_number) => {
    await db.collection(db_config.collectionName).remove(
    { mobile: mobile_number }
    )
})
}
deletor()
process.exit(0)

所有删除操作完成后,脚本应终止。但它会在删除操作完成之前终止。我想将此脚本添加到cron作业中,并且我想在所有异步操作完成后终止该脚本。

这怎么办?

2 个答案:

答案 0 :(得分:0)

您已经说过db.collection(...).remove(...)不会返回承诺,但是您会尝试一个。完成后:

forEach对回调的返回值不做任何事情,因此它不会做任何事情来等待您的async回调所创建的诺言得到解决。

相反,要并行运行它们,请使用mapPromise.all

await Promise.all(mobile_numbers.map(number => {
    return /*...create a promise for the remove operation here...*/;
}));

示例:

const removeNumber = number => new Promise(resolve => {
  console.log(`Removing ${number}...`);
  setTimeout(() => {
    console.log(`${number} removed`);
    resolve();
  }, Math.random() * 500);
});

async function deletor(mobile_numbers) {
    await Promise.all(mobile_numbers.map(number => {
        return removeNumber(number);
    }));
}

deletor(["111", "222", "333", "444", "555"])
    .then(() => { console.log("Done"); })
    .catch(err => { console.error("Error:", err); });

要连续运行它们,可以使用“ Promise reduce”技巧:

await mobile_numbers.reduce((p, number) => {
    return p.then(() => {
        return /*...create a promise for the remove operation here...*/
    });
}, Promise.resolve());

示例:

const removeNumber = number => new Promise(resolve => {
  console.log(`Removing ${number}...`);
  setTimeout(() => {
    console.log(`${number} removed`);
    resolve();
  }, Math.random() * 200);
});

async function deletor(mobile_numbers) {
    await mobile_numbers.reduce((p, number) => {
        return p.then(() => {
            return removeNumber(number);
        });
    }, Promise.resolve());
}

deletor(["111", "222", "333", "444", "555"])
    .then(() => { console.log("Done"); })
    .catch(err => { console.error("Error:", err); });

答案 1 :(得分:0)

1)尝试使用此代码

deletor().then(() => process.exit(0));

异步函数“ deletor()”返回一个promise。这意味着您可以使用在“ deletor()”之后执行的“ then()”方法。

另一种方法是使用异步“ main()”函数

async function deletor() {...}
async function main() {
    await deletor();
    process.exit(0);
 }
 main();

2)而不是“ .forEach(async ...)”,您应该使用其中一个

Promise.all(...)

for (const item of items) {
   await .....
}

第一种情况并行运行。秒运行序列。