我有问题,代码如下:
问题是:
promiseGetCitiesData
发送到promiseGetInformationDataPerCity
。async.each
函数中完成吗?现在,我创建了多个Promise函数。一个通用函数,一个启动程序 - getDataAndCloseDb()
。
我还使用async.each
使用数组参数调用promise函数 - locationArray
。
现在,我想将每一行从json响应发送到下一个promise函数(create get url),并收集一般响应。
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();
答案 0 :(得分:1)
我认为这比问题中的代码更容易出现。特别是,new Promise(...)
可以通过以下方式完全避免:
require('async-request')
代替require('request')
。另外
Promise.all(array.map(...))
模式,require('async')
的需求消失。有些猜测,我想你想要这样的东西:
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()
和promiseGetInformationDataPerCity()
进行一些更改。
答案 1 :(得分:0)
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);
});
})