【发布时间】:2017-02-05 07:00:28
【问题描述】:
我学习 Node 才几天。我决定切换到 Node 的原因是它比我曾经用作服务器端语言的 php 快得多。最近,我意识到在以递归方式发送请求和处理数据时,使用 php 并不是那么有效my previous post considering php and VK api。 (顺便说一句,我找到了解决方案)
所以我将我的函数重写为 Node,但由于 Node 的异步特性,它现在无法正常工作。
简而言之:这个函数必须找到社交网络用户之间的所有间接连接,并用每个找到的间接连接的数据填充数组connections(这也是一个包含字符串的数组每个链成员的数据(即名称、第二个名称和 id))。
var find_links = function(n, node1, ports,
vk, visited, connection, connections, event_count, callback) {
n+=1;
if(n<2) { // I don't want to go too far with my recursion. I keep track of it
// vk.request just send a request to api and gets a list of friends of a user with user_id: node1
vk.request('friends.get', {'user_id' : node1, 'fields' : 'domain, first_name'}, function(_o) {
// when we get response it may be either response or 'error' if user has deleted their account
if('response' in _o) { // just checking if we have response
for (var item of _o['response']['items']) {
for (var port of ports['response']['items']) {
if(port['id'] == item['id']) {
data = item['first_name'] + ' ' + item['last_name'] + ' ' + item['id']; // info about user
connection.push(data);
connections.push(connection);
connection.pop();
break;
}
else {
if (!visited.present(item['id'])) { // if we haven't encountered this user before
data = item['first_name'] + ' ' + item['last_name'] + ' ' + item['id']; // info about user
connection.push(data);
visited.push(item['id']); // we add user_id to visited array
// recursion
find_links(n, item['id'], ports, vk, visited, connection, connections, event_count, console.log);
connection.pop();
}
}
}
}
if (n == 1) {
callback("conn is "+connections);
}
}
else {
return 1;
}
});
}
else { // if n == 2, i check only friends of current user and return
vk.request('friends.get', {'user_id' : node1, 'fields' : 'domain, first_name'}, function(_o) {
if('response' in _o) {
for(item_ of _o['response']['items']) {
for(var arg_ of ports['response']['items']) {
if (arg_['id'] === item_['id'] && !visited.present(item_['id'])) {
data = item_['first_name'] + ' ' + item_['last_name'] + ' ' + item_['id'];
connection.push(data); // add data about user to connection
connections.push(connection);
connection.pop();
break;
}
else {
connection.pop();
}
}
}
}
return 1;
})
}
}
所以,当我记录 connections 数组时,该数组必须包含有关找到的所有链的数据,我得到了这个,,,,,,,,,,,,,,,,。项目只是没有被推送到数组中,是吗?
那么,我怎样才能让我的代码在循环中按顺序运行并等待递归函数完成后再继续?
当我请求好友时,VK 的回复如下所示:
{ response:
{ count: 67,
items:
[ { id: 6248811,
first_name: 'Екатерина',
last_name: 'Федорова',
domain: 'k.fedorova' },
{ id: 8102967,
first_name: 'Роман',
last_name: 'Соколинский',
domain: 'majestyk',
hidden: 1 },
.....
]
}
}
【问题讨论】:
-
这段代码有点混乱...你能提供一个精简版吗?可以直接推送数据,为什么还要push和pop呢?但是,您可以查看使用块范围变量(让 myvar = something)。这些不受您的外部范围的影响,并且在异步循环中非常方便。而现在回调并不是你真正的做法(看看承诺,例如github.com/kriskowal/q)
-
@Rienk 直接推送数据是什么意思?我需要在数组中推送和弹出数据,因为这样我可以跟踪我访问过的用户。目前,我认为这是最好的方法。
-
好的,这有点令人困惑。为什么不为访问过的用户创建一个对象? => var 连接 = {}; connections[userid] = 一些连接数据;然后检查是否已经访问过: if (typeof connections[otheruserid] === 'undefined'){connections[otheruserid] = some connection data;}else{continue;};
-
@Rienk 我已经有一个名为visited 的对象,它使用自定义方法'present' 检查项目是否在数组中。我将 user_ids 推送到该对象:因此该函数不再处理访问过的用户。而且我有对象连接来存储有关一个间接连接的信息,以及存储多个连接的连接对象。我需要连接以便以后能够呈现找到的所有间接连接
-
好的,我想我看到了一个问题(不是我想的全部,但是嘿..)。您正在递归调用 find_links,但我认为您需要在函数中返回它(return find_links(params);)。