簡體   English   中英

從async.each發送到兩個不同的功能

[英]From an async.each send to two differents functions

我正在嘗試做這樣的事情,我接收到對象數組的信息,然后使用async.each函數,調用將數據發送到另一個api的兩個函數,我正在使用ExpressJs。 這是代碼:

異步功能:

 async.each(readingsArray, function(reading, callback) {
    var firstTwo;
    firstTwo = reading.value.substring(0,2);
    if(firstTwo === '32') {
      updateLocation(reading, function() {
        callback();
      });
    } else {
      updateItem(reading, function() {
        callback();
      });
    }
  }, function(err) {
    if(err) {
      res.send(Boom.badRequest('Can't sent data'));
    } else {
      res.send({
        statusCode: 200,
        message: 'Data sent'
      });
    }
  });

和其他兩個功能:

    var updateLocation = function updateLocation (reading, callback) {
    request.patch(config.url + '/handhelds/' + reading.id)
    .send({
      //some information
    })
    .end(function(err, res) {
      if (err) {
        callback(err);
      } else {
        callback();
      }
    });
  };



  var updateItem = function updateItem(lectura, callback) {
  request.post(config.url + '/items/' + reading.id +    '/event')
  .send({
   //some information
  })
  .end(function(err, res) {
    if (err) {
      callback(err);
    } else {
        callback();
      }
    });
};

我仍在嘗試了解nodejs的異步部分。 我想做的是更新設備位置,然后,使用另一個功能updateItem發送項目,直到調用另一個updateLocation,然后繼續發送項目。 那就是為什么在異步中我放置一個if來標識位置或項目的原因。 可能嗎?

編輯1:

這是我使用的所有代碼:

'use strict';

var express = require('express');
var bodyParser = require('body-parser');
var request = require('superagent');
var async = require('async');
var moment = require('moment-timezone');
var Boom = require('boom');

var config = require('./config.js');

var app = express();

var getReadings = function getReadings(csvValue, mac) {
//Here I return the array of objects

  var readings, values;

  var arrayFromCSV = function arrayFromCSV(csv) {

    var array = values.replace(/\n/g, ',').replace(/\'/g, '').replace(/\"/g, '').split(',');
    array.pop(); 
    return array;
  };

  var epochToISO = function epochToISO(epochValue) {

    var epochInMilliseconds = parseInt(epochValue, 10) / 1000;
    var date = new Date(epochInMilliseconds);
    return date.toISOString();
  };

  var convertToArgentinaTimezone = function convertToArgTimezone(utcTime) {

    return moment.tz(utcTime, 'America/Argentina/Buenos_Aires').format();
  };

  var separateValues = function separateValues(readings) {

    var items = [];
    for (var i = 0; i < lecturas.length; i += 4) {
      var newObject = {
        epc: lecturas[i + 1],
        mac: mac,
        timeStamp: convertToArgentinaTimezone(epochToISO(lecturas[i + 2]))
      };
      items.push(newObject);
    }
    return items;
  };

  lecturas = arrayFromCSV(valorCSV);
  epcs = separarPorEPC(lecturas);

  return epcs;
};

 var updateLocation = function updateLocation (reading, callback) {
    request.patch(config.url + '/handhelds/' + reading.id)
    .send({
      //some information
    })
    .end(function(err, res) {
      if (err) {
        callback(err);
      } else {
        callback();
      }
    });
  };

var updateItem = function updateItem(lectura, callback) {
  request.post(config.url + '/items/' + reading.id +    '/event')
  .send({
   //some information
  })
  .end(function(err, res) {
    if (err) {
      callback(err);
    } else {
        callback();
      }
    });
};

app.use(bodyParser.urlencoded({
  extended: true
}));

app.post('/', function(req, res) {

  var readingsInValues = req.body.field_values;
  var mac = req.body.reader_name.replace(/\'/g, '').replace(/\"/g, '');
  var readingArrays = getReadings(readingsInValues, mac);
   async.each(readingsArrays, function(reading, callback) {
    var firstTwo;
    firstTwo = reading.value.substring(0,2);
    if(firstTwo === '32') {
      updateLocation(reading, function() {
        callback();
      });
    } else {
      updateItem(reading, function() {
        callback();
      });
    }
  }, function(err) {
    if(err) {
      res.send(Boom.badRequest('Can't sent data'));
    } else {
      res.send({
        statusCode: 200,
        message: 'Data sent'
      });
    }
  });
});

console.log('Traductor encendido');

app.listen(config.port);

該數組如下所示:

      [ { id: '32144B5A1231200000001',
        mac: '00:16:25:10:57:E9',
        timeStamp: '2015-11-20T10:28:26-03:00' },
      { id: '30142F13F44123F0000057',
        mac: '00:16:25:10:57:E9',
        timeStamp: '2015-11-20T10:28:28-03:00' },
      { id: '32144B1231230000001AB',
        mac: '00:16:25:10:57:E9',
        timeStamp: '2015-11-20T10:29:09-03:00' },
      { id: '30142F13F0234234000055',
        mac: '00:16:25:10:57:E9',
        timeStamp: '2015-11-20T10:30:19-03:00' } ]

希望這能澄清我的問題。

我假設您的readingsArray可能包含如下數據:

[
  '32_LocationA',
  '0000_someDataAboutLocationA',
  '0001_someDataAboutLocationA',
  '32_LocationB',
  '0002_someDataAboutLocationB',
  '0003_someDataAboutLocationB'
]

這是6條獨立的消息,以一定順序收集。

您應該了解的是, async.each將在不考慮順序的情況下同時發送所有消息。 您的if語句僅將每個消息路由到不同的URL(基於firstTwo值)。 我將其稱為您的discriminatorFn

如果您關心ORDER,則應該通過對需要按特定順序排列的消息進行分組來對數組進行預處理。 例如,您可能想在00000001消息之前發送32_LocationA消息。 32_LocationB00020003 我們稱這些為“批次”。

批次可能只是相關讀數的子數組,因此批次數組是2D數組,每個批次都按“正確”順序排列:

[
   // batch A:
   [ '32_LocationA', '0000...', '0001...' ],
   // batch B: 
   [ '32_LocationB', '0002...', '0003...' ]
]

對於每個批次,您可能要確保先調用updateLocation ,但是您可能並不關心哪個批次優先(可以同時發送)。 這是async.eachasync.eachSeries的用例,例如:

async.each(batches, function(batch, callback) {
  async.eachSeries(batch, discriminatorFn, callback); 
}, function(err) { 
  // results
});

eachSeries處理batch數組中的每個讀數,並等待迭代器函數( discriminatorFn )調用其callback參數,然后再調用下一個讀數。

希望這可以幫助。

編輯

// uses the `reduce` function to transform
// `p` is the accumulator, "previousValue"
// `c` is the current element of the array, "currentValue" 
var batched = readingsArray.reduce(function(p, c) {
  if(c.value.substring(0,2) == '32') { p.push([]); }
  p[p.length-1].push(c); 
  return p;
}, []);

如果request來自Express,則不是您要嘗試執行的操作,因此將無法使用。 它用於托管服務器以響應客戶端請求。

這將幫助您從代碼中進行http調用: https : //nodejs.org/api/http.html#http_http_request_options_callback 或者,您可以使用現有的軟件包來簡化代碼( 例如

異步不保證讀取數據的任何順序,您確定它就是您想要的嗎?

另外,您還可以簡化代碼, callback已經是一個函數,因此您無需將其包裝在函數中。

async.each(readingsArray, function (reading, callback) {
  var firstTwo;
  firstTwo = reading.value.substring(0, 2);
  if (firstTwo === '32') {
    updateLocation(reading, callback);      // <<<<<<<<<< here
  } else {
    updateItem(reading, callback);          // <<<<<<<<<< here
  }
}, function (err) {
  if (err) {
    res.send(Boom.badRequest("Can't sent data"));
  } else {
    res.send({
      statusCode: 200,
      message: 'Data sent'
    });
  }
});

var updateLocation = function updateLocation(reading, callback) {
  request.patch(config.url + '/handhelds/' + reading.id)
    .send({
      //some information
    }).end(callback);                       // <<<<<<<<<< here
};



var updateItem = function updateItem(lectura, callback) {
  request.post(config.url + '/items/' + reading.id + '/event')
    .send({
      //some information
    }).end(callback);                      // <<<<<<<<<< here
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM