我正在尝试使用Ebay API提供的2项服务:
findItemsByKeywords(keyword)
:返回项目列表(对象);
getItemTransactions(itemId)
:返回项目事务列表(对象);
在调用findItemsByKeywords
并获取返回的项目列表后,我需要调用getItemTransactions
并获取每个项目的交易并使用它们创建新列表。
我正在使用Node.js,Express,Ejs和MongoDB
我的代码仅适用于一次互动。
Error:
Error: unable to connect to database at mongodb://localhost/simplysell-development
at NativeConnection.<anonymous> (/Users/guilhermefalcao/workspace/simplysell/app.js:11:9)
at emitOne (events.js:96:13)
at NativeConnection.emit (events.js:188:7)
at Db.<anonymous> (/Users/guilhermefalcao/workspace/simplysell/node_modules/mongoose/lib/drivers/node-mongodb-native/connection.js:169:10)
at emitTwo (events.js:106:13)
at Db.emit (events.js:191:7)
at Server.listener (/Users/guilhermefalcao/workspace/simplysell/node_modules/mongodb/lib/db.js:1786:14)
at emitOne (events.js:96:13)
at Server.emit (events.js:188:7)
at Server.<anonymous> (/Users/guilhermefalcao/workspace/simplysell/node_modules/mongodb/lib/server.js:274:14)
at emitOne (events.js:96:13)
at Server.emit (events.js:188:7)
at Pool.<anonymous> (/Users/guilhermefalcao/workspace/simplysell/node_modules/mongodb-core/lib/topologies/server.js:334:12)
at emitOne (events.js:96:13)
at Pool.emit (events.js:188:7)
at Connection.<anonymous> (/Users/guilhermefalcao/workspace/simplysell/node_modules/mongodb-core/lib/connection/pool.js:270:12)
我不是想要访问数据库,我不知道为什么会出现这个错误。
我对代码和英语质量感到抱歉, 我现在开始 。
以下是一些代码:
router.get('/bestsellers', (req, res, next) => {
var i = 0;
var findItemsByKeywordsPromise = findItemsByKeywords('iphone');
findItemsByKeywordsPromise.then(items => {
var getItemTransactionsPromise = getItemTransactions(items);
return getItemTransactionsPromise;
}).then(test => console.log(test))
});
function getItemTransactions(items) {
return new Promise((resolve, reject) => {
var list = [];
items.forEach(function (item) {
ebay.xmlRequest({
serviceName: 'Trading',
opType: 'GetItemTransactions',
// app/environment
devId: 'xxxxxxx',
certId: 'xxxxxxx',
appId: 'xxxxxxx',
sandbox: false,
// per user
authToken: 'xxxxxxx',
params: {
'ItemID': item.itemId,
'NumberOfDays': 30
}
}, function (error, results) {
list.push(results)
resolve(list);
});
})
});
}
function findItemsByKeywords(keywords) {
return new Promise((resolve, reject) => {
var params = {
keywords: [keywords],
};
ebay.xmlRequest({
serviceName: 'Finding',
opType: 'findItemsByKeywords',
appId: 'xxxx', // FILL IN YOUR OWN APP KEY, GET ONE HERE: https://publisher.ebaypartnernetwork.com/PublisherToolsAPI
params: params,
parser: ebay.parseResponseJson // (default)
},
// gets all the items together in a merged array
function itemsCallback(error, itemsResponse) {
if (error) reject(error);
console.log('findItemsByKeywords called');
var items = itemsResponse.searchResult.item;
console.log('Found', items.length, 'items');
resolve(items);
}
);
});
}
答案 0 :(得分:-1)
查看代码,我们无法知道Mongo错误发生的原因。
但是回答标题中的答案,函数getItemTransactions
是错误的。您正在为数组中的每个项目调用resolve
,但Promise只能解析一次,因此它只会返回它解析的第一个项目。
我会用两个函数组织它:
function getItemTransaction (item) {
return Promise(function (resolve, reject) {
ebay.xmlRequest({
serviceName: 'Trading',
opType: 'GetItemTransactions',
// app/environment
devId: 'xxxxxxx',
certId: 'xxxxxxx',
appId: 'xxxxxxx',
sandbox: false,
// per user
authToken: 'xxxxxxx',
params: {
'ItemID': item.itemId,
'NumberOfDays': 30
}
}, function (error, results) {
if (error) {
return reject(error);
}
resolve(results);
});
});
}
function getItemTransactions(items) {
var promises = items.map(function(item) {
return getItemTransaction(item);
});
// Promise.all waits for all the promises to get resolved
// and return an array of resolved promises
return Promise.all(promises);
}
如果您在主代码中执行该操作,则可能不需要第二个函数:
findItemsByKeywords('iphone')
.then(items => {
return Promise.all(items.map(item => getItemTransaction(item));
})
.then(test => console.log(test));
答案 1 :(得分:-2)
那是对的。在ebay api返回一个值之前循环完成,因此解析将返回一个不完整的数组(列表)。
function getItemTransactions(items) {
return new Promise((resolve, reject) => {
var list = [];
items.forEach(function (item) {
ebay.xmlRequest({
serviceName: 'Trading',
opType: 'GetItemTransactions',
// app/environment
devId: 'xxxxxxx',
certId: 'xxxxxxx',
appId: 'xxxxxxx',
sandbox: false,
// per user
authToken: 'xxxxxxx',
params: {
'ItemID': item.itemId,
'NumberOfDays': 30
}
}, function (error, results) {
list.push(results)
if (list.length == items.length) {
resolve(list);
}
});
})
});
}
这是我改变的,我在列表数组完成时解析:
if (list.length == items.length) {
resolve(list);
}