使用顺序参数发出动态数量的请求
Making a dynamic number of requests with sequential parameters
我正在构建一个应用程序,我需要在其中发出从指定编号开始的按顺序编号的请求。这是我的第一个 node.js 项目,所以我边学边做,但我被困在这个特定问题上。
我需要传递 id 以便我以后可以参考。本质上,我需要使用第一个请求中的数据向不同的 api 发出第二个请求。对第二个请求的大部分数据将来自第一个请求的响应,但 id 不是,所以我需要以某种方式传递它。
const rp = require('request-promise');
var id = process.argv[2];
var numIterations = process.argv[3] || 5;
var apiRequests = [];
for (var i = 0; i < numIterations; i++) {
var requestDetails = {
uri: 'https://www.example.com/id=' + id,
json: false
};
apiRequests.push(
rp(requestDetails).then(
function (data) {
return {
id: id,
html: data
};
}
)
);
id++;
}
Promise.all(apiRequests)
.then((results) => {
for (var i = 0; i < results.length; i++) {
console.log(results[i].id); continue;
}
}).catch(err => console.log(err));
例如,如果 id = 1 和 numIterations = 5,那么我希望看到:
1个
2个
3个
4个
5
但我看到的是:
5个
5个
5个
5个
5
我知道为什么会发生这种情况,因为请求承诺的工作方式,但我不确定如何最好地解决它。
您的 apiRequest ({ id: id, html: data };
) 的结果 object
将在承诺得到解决后异步创建。在那一刻 id
变量分配了最新的值。因此所有创建的结果对象都将具有相同的值。
要解决此问题,您应该在每个 for
步骤中保留您的 ID 的引用。所以定义一个 array
来保存生成的 id 并将每个 id 推入其中,因为它与 apiRequests
具有相同的顺序,然后您可以通过 [=18] 的索引访问它们=].
var apiRequests = [];
var ids = [];
// ...
apiRequests.push(/* ... */);
ids.push(id);
// ...
console.log(ids[i]);
如果可能,替代解决方案将使用 let
而不是 var
。正如描述的那样 here:
var
is scoped to the nearest function block and let is scoped to the nearest enclosing block.
如果您在 for
中定义一个 let
变量,将在每个步骤中创建一个唯一的实例,因为它在您的对象中被引用,它将一直保留到您退出函数作用域。所以实现将是这样的:
for (var i = 0; i < numIterations; i++) {
let finalId = id; // add this line
var requestDetails = {
uri: 'https://www.example.com/id=' + id,
json: false
};
apiRequests.push(
rp(requestDetails).then(
function (data) {
return {
id: finalId, // update this line
html: data
};
}
)
);
id++;
}
我正在构建一个应用程序,我需要在其中发出从指定编号开始的按顺序编号的请求。这是我的第一个 node.js 项目,所以我边学边做,但我被困在这个特定问题上。
我需要传递 id 以便我以后可以参考。本质上,我需要使用第一个请求中的数据向不同的 api 发出第二个请求。对第二个请求的大部分数据将来自第一个请求的响应,但 id 不是,所以我需要以某种方式传递它。
const rp = require('request-promise');
var id = process.argv[2];
var numIterations = process.argv[3] || 5;
var apiRequests = [];
for (var i = 0; i < numIterations; i++) {
var requestDetails = {
uri: 'https://www.example.com/id=' + id,
json: false
};
apiRequests.push(
rp(requestDetails).then(
function (data) {
return {
id: id,
html: data
};
}
)
);
id++;
}
Promise.all(apiRequests)
.then((results) => {
for (var i = 0; i < results.length; i++) {
console.log(results[i].id); continue;
}
}).catch(err => console.log(err));
例如,如果 id = 1 和 numIterations = 5,那么我希望看到: 1个 2个 3个 4个 5
但我看到的是: 5个 5个 5个 5个 5
我知道为什么会发生这种情况,因为请求承诺的工作方式,但我不确定如何最好地解决它。
您的 apiRequest ({ id: id, html: data };
) 的结果 object
将在承诺得到解决后异步创建。在那一刻 id
变量分配了最新的值。因此所有创建的结果对象都将具有相同的值。
要解决此问题,您应该在每个 for
步骤中保留您的 ID 的引用。所以定义一个 array
来保存生成的 id 并将每个 id 推入其中,因为它与 apiRequests
具有相同的顺序,然后您可以通过 [=18] 的索引访问它们=].
var apiRequests = [];
var ids = [];
// ...
apiRequests.push(/* ... */);
ids.push(id);
// ...
console.log(ids[i]);
如果可能,替代解决方案将使用 let
而不是 var
。正如描述的那样 here:
var
is scoped to the nearest function block and let is scoped to the nearest enclosing block.
如果您在 for
中定义一个 let
变量,将在每个步骤中创建一个唯一的实例,因为它在您的对象中被引用,它将一直保留到您退出函数作用域。所以实现将是这样的:
for (var i = 0; i < numIterations; i++) {
let finalId = id; // add this line
var requestDetails = {
uri: 'https://www.example.com/id=' + id,
json: false
};
apiRequests.push(
rp(requestDetails).then(
function (data) {
return {
id: finalId, // update this line
html: data
};
}
)
);
id++;
}