【问题标题】:async.each callback inside async.waterfall not triggeredasync.waterfall 中的 async.each 回调未触发
【发布时间】:2018-07-05 10:21:41
【问题描述】:

我正在努力实现以下目标:

请考虑在尚不支持 async/await 的 jasmine 测试框架中运行它

async.waterfall 调用具有 async.each 的函数来触发模式和表的创建。异步瀑布中的步骤必须按顺序执行,即必须在创建表之前创建模式。我面临的问题是执行创建模式的第一个调用,但回调从未返回到 async.waterfall。因此, async.waterfall 中的下一步永远不会执行。

时间线或流程:
driverFunction (async.waterfall) 调用 createFunction
createFunction(asyncCreateSchema 等)函数为数组中的每个文件调用 doSomething
doSomething 执行一个 jar 文件并返回成功或错误。

这是我的代码:

'use strict'
let async = require('async');


function doSomething(file, done) {
  console.log(file);
  return done(null, true);
}

function asyncCreateSchema(files, done) {
  async.each(
    files,
    function(file, callback) {
      if (file.startsWith('schema')) {
        doSomething(file, callback);
      }
      else{
        callback();
      }
    },
    function(err) {
      if (err) {
        console.log(err);
      }
      console.log('create schema done');
    });
}

function asyncCreateTables(files, done) {
  async.each(
    files,
    function(file, callback) {
      if (file.startsWith('table')) {
        doSomething(file, callback);
      }
      else{
        callback();
      }
    },
    function(err) {
      if (err) {
        console.log(err);
      }
      console.log('create schema done');
    });
}

var files = ['schema.json', 'schema_1.json', 'table.json'];

async.waterfall([
    next => asyncCreateSchema(files, next),
    (nil, next) => asyncCreateTables(files, next),

  ],
  function(err, res) {
    if (err) {
      throw new Error("Setup error: " + err.message);
    } else {
      console.log(res);
    }
  }
);

我在这里做错了什么?请使用 async npm 包说明本场景中回调函数的流程。

【问题讨论】:

  • else 的情况下(不存在)callback 永远不会被调用
  • 我也试过了:function(err){ if(err) { console.log(err); } done(null, true); } 它永远不会到达这条线。
  • 不在结果回调中,在迭代回调中! if (file.startsWith('schema')) { doSomething(file, callback); } else /* hang! */;
  • @Bergi 牛眼。但是控制权还没有返回到瀑布!

标签: javascript node.js asynchronous callback jasmine-node


【解决方案1】:

你为什么使用 async.wattherfall 函数而不是 ES2017 async/await

请给我看更多代码,一些异步代码不仅仅是console.log(),看看我怎样才能去掉那个丑陋的nodejs异步库并用纯async/await语法替换。

我刚刚给你做了一些代码,但我不知道你想要什么,请把你的代码的时间线也写上,例如这个fn在前面,然后结果用在另一个一个。

async function doSomething(file) {
    var result = await new Promise((done, error) => {
        console.log(file)
        /* Here you execute async or sync operatios,
           when done, fire the done() if there is an error, you fire the error(error) */
        someTask(file, function(err, data){
            if (err)
                error(err)
            else
                done(data) //This data will be in result
        })
    })
    return result //data passed to done()
}

async function asyncCreateSchema(files, done) {
    for (var file of files) {
        if (file.startsWith('schema'))
            await doSomething(file);
    }
}

async function asyncCreateTables(files) {
    for (var file of files) {
        if (file.startsWith('table'))
            await doSomething(file);
    }
}


async function noNeedOfWaterfall () {
    var files = ['schema.json', 'schema_1.json', 'table.json']
    await asyncCreateSchema(files)
    await asyncCreateTables(files)
}

noNeedOfWaterfall()
    .then(() => console.log('all done'))
    .catch(e => {
        console.log('If you fire the error(err) in doSomething >>', e)
    })

【讨论】:

  • 感谢详细的解释!您假设的流程是正确的: driver 函数调用创建函数,对于目录中的 每个文件,create 函数调用 doSomething 最终执行一个java jar。关于使用:异步包已经包含在我正在处理的项目中。我相信 async 包可以更容易地编写可读代码,并且还提供了许多 ES2017 功能。虽然你给了我一个完美的代码,但如果你能理解回调是如何在异步包中工作的,那就太好了。
  • 你不认为带有for循环和await的create函数是顺序的吗?我正在尝试实现并行性:例如,如果有十个模式文件,则该函数应该能够并行触发这些文件。
  • 当然,如果你想实现并行,有Promise.all[array of data to process]可以让你得到结果,直到所有的都完成。
猜你喜欢
  • 1970-01-01
  • 2016-07-01
  • 2015-06-05
  • 2015-07-20
  • 2014-09-06
  • 2011-02-12
  • 2020-08-08
  • 1970-01-01
相关资源
最近更新 更多