我正在尝试从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);
}
);
});
}
查看代码,我们不知道为什么会发生mongo错误。
但是回答标题中的答案,函数 getItemTransactions
是错误的。您正在为数组中的每个项目调用resolve
,但是承诺只能解决一次,因此它只会回馈其解决的第一项。
我将以两个功能组织:
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));
是正确的。eBay API返回值之前的循环完成,因此解决方案将返回不完整的数组(list)。
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);
}