从命令行运行异步代码,Node.js

10

我有一个函数生成一些测试数据并将其插入到mongodb数据库:

'use strict';
const CvFaker = require('./cv-faker');
const mongoose = require('mongoose');
require('../models/cv_model.js');

module.exports.init = function(){
  var cvfaker = new CvFaker();
  cvfaker.genCvs(100);

  mongoose.model('cv').create(cvfaker.cvs, (err, createdCvs) => {
    if(err){
      console.log('something went wrong');
    }

  })
};
我想要从命令行执行这段代码:
node -e 'require("./create-mock-db").init()'

该函数会执行,但由于是异步的,它不会等待函数完成。我该如何让它等待函数完成后再继续执行?

这个也不起作用:

module.exports.init = function(cb){ ...
..
cb();

node -e 'require("./create-mock-db").init(function(){})'

在Javascript中,函数不会等待异步操作完成。它们只是不会。通常,您可以使用完成回调来在异步操作完成后继续逻辑。如果您描述了您试图通过等待解决的实际问题,我们可能可以帮助您找到替代方案。 - jfriend00
是的,但我如何在从命令行执行时添加回调函数? - Joe
1
为什么不自己创建一个脚本,加载这个模块并按照预期使用完成回调呢?在控制台一行一行地编写复杂的代码很困难。但是,你可以将一个回调函数传递给.init(),当异步操作完成时会调用该回调函数。 - jfriend00
由于这段代码不应该在生产环境中运行,只能在开发模式下使用,我不想将其暴露出去,因此我想从命令行执行它。但是如果你的代码是异步的,我找不到任何方法来执行它。 - Joe
在控制台上这样做很疯狂!但是,您可以先在控制台中键入一个函数,以便定义其符号。然后,将该符号作为回调函数作为参数传递给.init() - jfriend00
显示剩余4条评论
3个回答

2
node 进程在事件队列为空之前不会退出。 事件循环 使用事件队列使异步执行成为可能。
验证这不是执行异步代码的问题非常简单。
node -e "setTimeout(() => console.log('done'), 5000)"

这个例子需要5秒钟才能运行,这是您预期的结果。


你的代码问题在于你从未与数据库建立连接。在有连接之前,model.create方法不会执行任何操作,因此没有任何东西被排队,进程可以自由退出。

这意味着你的代码需要做两件事情:

  1. 连接到数据库,以便model.create方法可以执行。
  2. model.create完成时断开与数据库的连接,以便进程可以自由退出。

2
作为这个答案可能会面对更多人的情况,我认为需要进行一些补充说明。
// test.js
const request = require('request');
const rp = require('request-promise');

const demo = module.exports.demo = async function() {
  try {
    const res = await rp.post( {
      uri: 'https://httpbin.org/anything',
      body: { hi: 'there', },
    }, function (error, response, body) {
      return error ? error : body;
    } )
    console.log( res )
    return res;
  }
  catch ( e ) {
    console.error( e );
  }
};

像这样调用:

$ node -e 'require("./test").demo()'

旁注:

它并不等待函数完成,因为它是异步的。

它不是异步的。你可能调用了异步函数,但你没有将它们视为异步函数,并且没有 await 任何结果。


这应该是被接受的答案。 - salouri

0

补充Kaiser的回答,如果你在Windows上使用cmd,单引号/双引号很重要。将双引号放在外面,即

node -e "require('./test').demo()"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接