Javascript 如何使用json响应创建另一个URL。Nodejs
我有一个问题,代码如下: 问题是:Javascript 如何使用json响应创建另一个URL。Nodejs,javascript,node.js,mongodb,parsing,promise,Javascript,Node.js,Mongodb,Parsing,Promise,我有一个问题,代码如下: 问题是: 如何将responsepromiseGetCitiesData中的每一行发送到promiseGetInformationDataPerCity 我可以在一个async中完成它吗?每个都可以运行吗 现在,我创建了多个Promise函数。一个通用函数,该函数启动程序-getDataAndCloseDb() 我还使用了async.each调用带有数组参数的promise函数-locationArray 现在,我想将json响应中的每一行发送到下一个承诺函数(crea
promiseGetCitiesData
中的每一行发送到promiseGetInformationDataPerCity
async中完成它吗?每个都可以运行吗
getDataAndCloseDb()
我还使用了async.each
调用带有数组参数的promise函数-locationArray
现在,我想将json响应中的每一行发送到下一个承诺函数(creategetURL),并收集一般响应
const MongoClient = require("mongodb").MongoClient;
const request = require("request");
const async = require("async");
var locationsArray = [
'location1',
'location2',
'location3'
];
function promiseConnectToDatabase(urldb) {
return new Promise(function(resolve, reject) {
MongoClient.connect(urldb, (err, db) => {
if (err) {
console.log("MongoDb connection error.");
reject(err);
}
console.log("Connected to MongoDb.");
resolve(db);
});
});
}
function promiseGetCitiesData(location) {
return new Promise(function(resolve, reject) {
request({
url: `https://example.com/${location}`,
json: true
}, (error, response, body) => {
if (error) {
console.log("Error connection to url.");
reject();
}
console.log("location: " + location);
console.log({location: location, cities: body.result.cities});
resolve({location: location, cities: body.result.cities});
});
});
}
/*
Example response from promiseGetCitiesData:
Location: location1
{ location: 'location1',
cities:
[ 'information1',
'information2',
'information3',
'information4'' ] }
*/
function promiseGetInformationDataPerCity(location, cities) {
return new Promise(function(resolve, reject) {
request({
url: `https://example.com/${location}/${cities}`,
//f.e https://example.com/location1/information1 etc.
json: true
}, (error, response, information) => {
if (error) {
console.log("Error connection to url.");
reject();
}
console.log(information);
resolve(information);
});
});
}
function promiseSaveDataToDatabase(db, body) {
return new Promise(function(resolve, reject) {
db.collection("testlocation").insert(body, function(dbError) {
if (dbError) {
reject(dbError);
}
resolve()
});
});
}
function promiseDisconnectDatabase(db) {
return new Promise(function(resolve, reject) {
db.close((err) => {
if (err) {
console.log("MongoDb disconnect error.");
reject(err);
}
console.log("MongoDb disconnected.");
resolve();
});
});
}
function promiseProvideDataFromEach(locationsArray, db) {
return new Promise(function(resolve, reject) {
async.each(locationsArray, function(loc, locProcessedCb) {
promiseGetcitiesData(loc).then(function(resultscities) {
promiseGetInformationDataPerCity(loc, resultscities).then(function(resultDetails) {
promiseSaveDataToDatabase(db, resultDetails).then(function() {});
locProcessedCb();
});
});
}, function(err) {
if (err) {
locProcessedCb(err);
reject(err);
}
console.log("All locations have been processed.");
resolve();
});
});
}
function getDataAndCloseDb() {
return new Promise(function(resolve, reject) {
promiseConnectToDatabase("mongodb://127.0.0.1:27017/testApp").then(function(db) {
promiseProvideDataFromEach(locationsArray, db).then(function() {
promiseDisconnectDatabase(db).then(function() {});
});
});
});
}
getDataAndCloseDb();
你可以这样做。这是一个更简单的代码,但我认为您可以将其映射到当前代码
const Promise = require('bluebird')
const cities = ['citya', 'cityb', 'cityc']
function resolveCities() {
return new Promise(function(resolve, reject) {
resolve(cities)
})
}
function logCity(city) {
console.log('city ', city)
}
return resolveCities()
.then(function(cities) {
return Promise.mapSeries(cities, function(city) {
logCity(city);
});
})
我认为这比问题中的代码看起来要简单得多。特别是,
新承诺(…)
可以通过以下方式完全避免:
- 使用
而不是require('async-request')
require('request')
- 允许MongoDb方法返回承诺,如果不传递回调,许多方法都会返回承诺李>
- 通过使用
模式,对Promise.all(array.map(…)
的需求消失了require('async')
- -提供了一个非常有用的可重复使用处理器实用程序
- 记住从每个.then()回调返回一个承诺/值,该回调本身是异步的,并且/或者应该传递数据
const MongoClient = require('mongodb').MongoClient;
const request = require('async-request'); // just like `request()` but returns a promise
var locationsArray = [
'location1',
'location2',
'location3'
];
function promiseGetCitiesData(loc) {
return request({
url: `https://example.com/${loc}`,
json: true
}).then(body => body.result.cities);
}
function promiseGetInformationDataPerCity(loc, cities) {
return Promise.all(cities.map(city => {
return request({
'url': `https://example.com/${loc}/${city}`,
'json': true
}).then(cityInfo => ({ 'name':city, 'info':cityInfo }));
}));
}
function promiseProvideDataFromEach(locationsArray, db) {
return Promise.all(locationsArray.map(loc => {
return promiseGetCitiesData(loc)
.then(cities => promiseGetInformationDataPerCity(loc, cities)
.then(citiesWithCityInfo => ({ 'location':loc, 'cities':citiesWithCityInfo }));
}))
.then(resultDetails => db.collection('testlocation').insertMany(resultDetails));
}
// disposer utility - credit: https://stackoverflow.com/a/28915678/3478010
function withDb(work) {
var _db;
return MongoClient.connect("mongodb://127.0.0.1:27017/testApp")
.then((db) => {
_db = db; // keep reference
return work(db); // perform work on db
}).finally(() => {
if (_db)
_db.close();
});
}
withDb(db => promiseProvideDataFromEach(locationsArray, db))
.then(() => {
// connection released here
});
猜测主要集中在
db.collection('testlocation').insertMany(resultDetails)
中要插入的内容。问题中的代码只提供了一个线索。我的尝试似乎合理,但可能不是你想要的。请准备在promiseProvideDataFromEach()
和promiseGetInformation Datapercity()
中进行一些更改,我很难理解您想要做什么。您可以检查Promise。所有
模式都可以满足您的要求。我想将响应从promiseGetCitiesData{…“location1”、“location2”…等
发送到promiseGetInformationDataPerCity
(如代码中的注释)。最好的解决方案是每行发送:1。发送位置请求,获取包含信息的json。2.将响应json中的每一行发送到promiseGetCitiesData,收集响应,保存到数据库。3.再次发送位置2等请求。@Antonio Narkevich您是node js、java脚本技术的专家。您能检查一下我的问题吗?我在promiseGetInformationDataPerCity(位置,城市)
中有点困惑,url是按https://example.com/${location}/${cities}
<代码>位置只要是字符串就可以了。但是cities
(复数)是由promiseGetcitiesData()
交付的数组。那么应该将cities
合并成一个字符串,还是应该是https://example.com/${location}/${city}/
在某种循环中?@Roamer-1888感谢您的回复。就像我描述的那样。在调用promiseGetCitiesData之后,我得到了“promiseGetCitiesData的示例响应”(json带有“information1”、“information2”等字样)“我想发送到:promiseGetInformationDataPerCity,并使用它来创建URL地址,如:。。。及。你安装蓝鸟模块了吗?在我这方面工作正常。是的,bluebird模块已经安装。但是我不能解析每一行来调用另一个promise函数。所有这些都在一起-应该异步工作。第一次调用promiseGetCitiesData,每条线路都应该一个接一个地发送给另一个promiseGetCitiesData,然后第二次调用PromiseCitiesData。好的,为了更好地了解您的问题,您想根据一些数据向promiseGetCitiesData发送多个调用吗?请给我一个示例,说明您希望在每个请求中发送给promiseGetCitiesData
的数据。如果您希望逐个执行,则必须使用同步流而不是异步流。如我的说明所示。调用promiseGetCitiesData
后,我得到了“promiseGetCitiesData的示例响应”(json带有“information1”、“information2”等字样)“我想发送到:promiseGetInformationDataPerCity
,并使用它来创建URL地址,如:https://example.com/location1/information1, https://example.com/location1/information2... https://example.com/location1/informationN
和https://example.com/location2/information1... https://example.com/location2/informationN... https://example.com/locationN/informationN.
谢谢。我仍然对所有这些都有问题:then(cityInfo=>{'name':city,'info':cityInfo})代码>-错误-意外“:“令牌”
。如果我删除到,f.e.:然后(cityInfo=>body.result);
-错误是:“arequest=async(url,options)”
。然后(citiesWithCityInfo=>{'location','cities':citiesWithCityInfo});
。好的,缺少()在json响应中。但现在我仍然有async请求/src/main.js:141 arequest=async(url,options)=>{
错误。是的,我的错,这些都是“.我忘记了括号!答案已编辑。promiseGetCitiesData()
也包含错误。已编辑。我也做了更改(在promiseGetCitiesData上)但是我仍然有错误,就像我最后的评论:async request/src/main.js:141 arequest=async(url,options)=>{Unexpected token(.
但是没有关于行的信息。奇怪的错误。就像来自async request包。