我有一个Web请求,该请求获取一些数据并返回响应。我正在寻找如何将响应存储在变量中,以便稍后在代码中使用它。
这是针对在lambda函数中运行的节点js
/ ** *主要执行与车辆接口操作的操作 * Amazon DynamoDB表。 * * @级车 * /
/**
* Registers a vehicle to and owner.
* @param {JSON} ticket - authentication ticket
* @param {JSON} vehicle - vehicle object
* @param {createVehicle~callback} cb - The callback that handles the response.
*/
vehicle.prototype.createVehicle = function(ticket, vehicle, cb) {
let vehicle_data = [];
vehicle_data.push(vehicle);
let vin_data = _.pluck(vehicle_data, 'vin');
let vin_number = vin_data[0];
console.log(vin_number);
var options = {
url: 'https://vindecoder.p.mashape.com/decode_vin?' + 'vin=' + vin_number,
headers: {"X-Mashape-Key": "XXXXXXXXXXXXXXXXXXXXXXXXXX","Accept": "application/json"}
};
var data;
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
var result = JSON.parse(body);
var data = result['specification'];
//console.log(data);
}
}
request(options, callback);
var year = data['year'];
var make = data['make'];
var model = data['model'];
var trim_level = data['trim_level'];
var engine = data['engine'];
var body_style = data['style'];
var made_in = data['made_in'];
var steering_type = data['steering_type'];
var anti_brake_system = data['anti_brake_system'];
var fuel_tank = data['tank_size'];
var overall_height = data['overall_height'];
var overall_length = data['overall_length'];
var overall_width = data['overall_width'];
var standard_seating = data['standard_seating'];
var optional_seating = data['optional_seating'];
var highway_mileage = data['highway_mileage'];
var city_mileage = data['city_mileage'];
vehicle.owner_id = ticket['cognito:username'];
// vehicle.vehicle_year = year;
// vehicle.make = make;
// vehicle.model = model;
// vehicle.trim_level = trim_level;
// vehicle.engine = engine;
// vehicle.body_style = style;
// vehicle.made_in = made_in;
// vehicle.steering_type = steering_type;
// vehicle.anti_brake_system = anti_brake_system;
// vehicle.fuel_tank = fuel_tank;
// vehicle.overall_height = overall_height;
// vehicle.overall_length = overall_length;
// vehicle.overall_width = overall_width;
// vehicle.standard_seating = standard_seating;
// vehicle.optional_seating = optional_seating;
// vehicle.highway_mileage = highway_mileage;
// vehicle.city_mileage = city_mileage;
let params = {
TableName: ddbTable,
Item: vehicle
};
let docClient = new AWS.DynamoDB.DocumentClient(dynamoConfig);
docClient.put(params, function(err, data) {
if (err) {
console.log(err);
return cb(err, null);
}
return cb(null, vehicle);
});
};
我希望api调用的响应存储在一个对象中,以便可以用来更新dynamodb记录
答案 0 :(得分:0)
您的代码中存在各种问题。请参阅我在代码中留下的注释。 您的函数由于javascript的异步特性而失败。基本上,您有一个请求回调,其结果在其余代码中都看不到。使用promise和async / await是解决此问题的一种干净方法。见下文:
// use request promise instead of request
// promises will make your life much easier
// https://hackernoon.com/javascript-promises-and-why-async-await-wins-the-battle-4fc9d15d509f
// https://github.com/request/request-promise
const request = require('request-promise')
vehicle.prototype.createVehicle = function(ticket, vehicle, cb) {
// No need to use var anymore with es6, just use let and const
// https://www.sitepoint.com/es6-let-const/
let vehicle_data = [];
vehicle_data.push(vehicle);
let vin_data = _.pluck(vehicle_data, "vin");
let vin_number = vin_data[0];
console.log(vin_number);
const options = {
uri: "https://vindecoder.p.mashape.com/decode_vin?" + "vin=" + vin_number,
headers: {
"X-Mashape-Key": "XXXXXXXXXXXXXXXXXXXXXXXXXX",
Accept: "application/json"
}
};
// Here's the main mistake
// request has a callback function that is asynchronous
// the rest of your code never sees the result because the result doesn't leave the callback
// your code continues to execute without waiting for the result (this is the gist of asynchronity in js)
// function callback(error, response, body) {
// if (!error && response.statusCode == 200) {
// const result = JSON.parse(body);
// const data = result["specification"]; // this variable doesn't leave the scope of this callback
// //console.log(data);
// }
// }
// therefore this is the failure point
// request(options, callback);
// Do this instead
// here I utilize promises and async/ await
// https://medium.com/codebuddies/getting-to-know-asynchronous-javascript-callbacks-promises-and-async-await-17e0673281ee
try {
const result = await request(options);
const data = result["specification"];
} catch (error) {
console.log(error);
}
// Now data is available to be used below in dynamodb
// also, utilize objects, its much cleaner
const carVariables = {
year: data["year"],
make: data["make"],
model: data["model"],
trim_level: data["trim_level"],
engine: data["engine"],
body_style: data["style"],
made_in: data["made_in"],
steering_type: data["steering_type"],
anti_brake_system: data["anti_brake_system"],
fuel_tank: data["tank_size"],
overall_height: data["overall_height"],
overall_length: data["overall_length"],
overall_width: data["overall_width"],
standard_seating: data["standard_seating"],
optional_seating: data["optional_seating"],
highway_mileage: data["highway_mileage"],
city_mileage: data["city_mileage"],
};
vehicle.owner_id = ticket["cognito:username"];
vehicle = { ...vehicle, ...carVariables} // ES6 spread operator does the below code for you:
// one line versus 20. win. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
// vehicle.vehicle_year = year;
// vehicle.make = make;
// vehicle.model = model;
// vehicle.trim_level = trim_level;
// vehicle.engine = engine;
// vehicle.body_style = style;
// vehicle.made_in = made_in;
// vehicle.steering_type = steering_type;
// vehicle.anti_brake_system = anti_brake_system;
// vehicle.fuel_tank = fuel_tank;
// vehicle.overall_height = overall_height;
// vehicle.overall_length = overall_length;
// vehicle.overall_width = overall_width;
// vehicle.standard_seating = standard_seating;
// vehicle.optional_seating = optional_seating;
// vehicle.highway_mileage = highway_mileage;
// vehicle.city_mileage = city_mileage;
let params = {
TableName: ddbTable,
Item: vehicle
};
// This will now probably work. yay!
let docClient = new AWS.DynamoDB.DocumentClient(dynamoConfig);
docClient.put(params, function(err, data) {
if (err) {
console.log(err);
return cb(err, null);
}
return cb(null, vehicle);
});
};
这未经测试,但我认为应该可以。可能会有一些错别字或其他任何东西,但主要的收获是使用promise和async / await等待并暴露请求的结果。请参阅评论中的链接和参考,以进一步阅读。