具有异步任务的同步任务

时间:2016-12-20 07:07:30

标签: javascript node.js asynchronous async.js

我在一个应用程序上放置一个验证组件,它接受一个任务名称(可以是一个字段名称)和一个值作为它的参数。对于每个找到的表单字段,都会启动任务。

如果验证失败,则返回错误,否则输入正常,下一个字段任务将启动,直到处理完所有字段。

通过下面的示例,task_1按预期工作。但是,如果可能需要 HTTP 请求(由setTimeout模拟),则task_2不会返回所需的结果。

我确信这与异步性有关,也许有更好的方法来实现这种机制。这实际上将在{strong> NodeJS 后端实现,async库可用,我会接受使用Async的解决方案。

请参阅以下Fiddle以获取以下示例。或者这个{{3}}用于异步实现。



/**
 * Selecting task_1 below, will have the desired results,
 * however if you run task_2 the final task will not work?
 * A setTimeout() has been used to simulate a HTTP request etc..
 */

// output element
var $output = $$('output')

// configuration object, each task has an 
// array of functions which must accept a
// value which would be validated
var jobs = {
  task_1: [
    function(val, cb) {
      cb(null, val)
    },
    function(val, cb) {
      cb('Error', null)
    }
  ],
  task_2: [
    function(val, cb) {
      cb(null, val)
    },
    function(val, cb) {
      setTimeout(function() {
        cb('An ajax request has an error', null)
      }, 2000)
    }
  ]
}

// run a task and pass a value
taskRunner('task_2', 'Karl')

// taskRunner
function taskRunner(job, val) {
  var tasks = jobs[job]
  var errors = []

  if (tasks) {
    // run the found tasks
    for (i = 0; i < jobs[job].length; i++) {
      tasks[i](val, function(err, result) {
        if (err) {
          errors.push(err)
        }
      })
    }

    // generate the html output
    var html = errors.length > 0 ? [
      '<strong class="text-danger">',
      'Failure</strong>',
      '<pre>',
      errors,
      '</pre>'
    ].join('') : [
      '<strong class="text-success">',
      'Success</strong>',
      '<pre>All validations passed</pre>'
    ].join('')
    $output.html(html).fadeIn()
  } else {
    // return an error message if no tasks have been found
    $output.html('<span class="text-danger">There are no tasks for ' + job + '.</span>').fadeIn()
  }
}

// select elements by data attribute
function $$(val) {
  return $('[data-' + val + ']')
}
&#13;
/* default */
html,
body {
  margin: 0;
  padding: 0;
  font-family: "Lucida Console", Monaco, monospace !important;
  background: whitesmoke;
  color: #333;
}


/* output container */
.output {
  max-width: 75%;
  margin: 5% auto;
  padding: 15px;
  border: 1px solid #ddd;
  border-radius: 3px;
  background: white;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
}


/* formatted output */
pre {
  background: #FAFAFA;
  padding: 15px;
  margin-bottom: 0;
}


/* type styles */
.text-muted {
  opacity: .5
}

.text-danger {
  color: #D00
}

.text-success {
  color: #0D0
}


/* hide if empty */
.js-hide {
  display: none
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="output js-hide" data-output></div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

你应该在完成所有回调后生成html输出

为此目的,您可以使用promise.all

但是对于回调,您可以使用此代码

var doneCallback=0;
for (i = 0; i < jobs[job].length; i++) {
  tasks[i](val, function(err, result) {
    if (err) {
      errors.push(err)
    }
    doneCallback++;
    if(doneCallback==jobs[job].length)generateHtml();
  })
}

// generate the html output
function generateHtml(){
  var html = errors.length > 0 ? [
     '<strong class="text-danger">',
     'Failure</strong>',
     '<pre>',
     errors,
     '</pre>'
   ].join('') : [
     '<strong class="text-success">',
     'Success</strong>',
     '<pre>All validations passed</pre>'
   ].join('')
   $output.html(html).fadeIn();
}

&#13;
&#13;
/**
 * Selecting task_1 below, will have the desired results,
 * however if you run task_2 the final task will not work?
 * A setTimeout() has been used to simulate a HTTP request etc..
 */

// output element
var $output = $$('output')

// configuration object, each task has an 
// array of functions which must accept a
// value which would be validated
var jobs = {
  task_1: [
    function(val, cb) {
      cb(null, val)
    },
    function(val, cb) {
      cb('Error', null)
    }
  ],
  task_2: [
    function(val, cb) {
      cb(null, val)
    },
    function(val, cb) {
      setTimeout(function() {
        cb('An ajax request has an error', null)
      }, 2000)
    }
  ]
}

// run a task and pass a value
taskRunner('task_2', 'Karl')

// taskRunner
function taskRunner(job, val) {
  var tasks = jobs[job]
  var errors = []

  if (tasks) {
    // run the found tasks
    var doneCallback=0;
    for (i = 0; i < jobs[job].length; i++) {
       tasks[i](val, function(err, result) {
          if (err) {
            errors.push(err)
          }
          doneCallback++;
          if(doneCallback==jobs[job].length)generateHtml();
       })
    }

    // generate the html output
    function generateHtml(){
       var html = errors.length > 0 ? [
         '<strong class="text-danger">',
         'Failure</strong>',
         '<pre>',
          errors,
         '</pre>'
        ].join('') : [
          '<strong class="text-success">',
          'Success</strong>',
          '<pre>All validations passed</pre>'
        ].join('')
       $output.html(html).fadeIn();
     }
  } else {
    // return an error message if no tasks have been found
    $output.html('<span class="text-danger">There are no tasks for ' + job + '.</span>').fadeIn()
  }
}

// select elements by data attribute
function $$(val) {
  return $('[data-' + val + ']')
}
&#13;
/* default */
html,
body {
  margin: 0;
  padding: 0;
  font-family: "Lucida Console", Monaco, monospace !important;
  background: whitesmoke;
  color: #333;
}


/* output container */
.output {
  max-width: 75%;
  margin: 5% auto;
  padding: 15px;
  border: 1px solid #ddd;
  border-radius: 3px;
  background: white;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
}


/* formatted output */
pre {
  background: #FAFAFA;
  padding: 15px;
  margin-bottom: 0;
}


/* type styles */
.text-muted {
  opacity: .5
}

.text-danger {
  color: #D00
}

.text-success {
  color: #0D0
}


/* hide if empty */
.js-hide {
  display: none
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="output js-hide" data-output></div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

awk  -v line='DELIMITER AS '"'|'"'' '1; /LOAD_FILE/{print line }' input
FROM LOCAL :LOAD_FILE
DELIMITER AS '|'
REJECTED DATA :REJECT_PATH