为什么 async.series 只产生一个输出
Why async.series only produce one output?
>我有以下代码,它使用 got
和 async.series
向randomuser API
发出 10 个请求。出于某些原因,这只给了我一个输出。我该如何解决这个问题?
const got = require('got');
const async = require('async');
var tenOperations = [];
for(var i = 0; i < 10; i++) {
tenOperations.push(doRequest);
}
function doRequest(callback) {
got('https://randomuser.me/api/')
.then(response => {
console.log(response.body);
})
.catch(error => {
console.log(error.response.body);
});
};
async.series(tenOperations, function(err, results) {
if(err) console.log(err);
console.log(results);
});
Here is the sample output
:
{
"results": [
{
"user": {
"gender": "female",
"name": {
"title": "miss",
"first": "غزل",
"last": "كامياران"
},
"location": {
"street": "6186 آزادی",
"city": "رشت",
"state": "تهران",
"zip": 64318
},
"email": "غزل.كامياران@example.com",
"username": "goldenpanda201",
"password": "muscles",
"salt": "OStU2tyA",
"md5": "92ac8a84380a24785597d0e916b0174e",
"sha1": "93f6e830538dbc557017011583cca3b5e527f854",
"sha256": "99a4c35237b1ebe276732fbf62efca24fd457428853de8a967dd465b80b82f0f",
"registered": 1352433856,
"dob": 1370066399,
"phone": "053-14062122",
"cell": "0929-641-1309",
"picture": {
"large": "https://randomuser.me/api/portraits/women/48.jpg",
"medium": "https://randomuser.me/api/portraits/med/women/48.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/women/48.jpg"
}
}
}
]
}
如果您只想按顺序向同一 API 发出十个请求(一个接一个,而不是并行),您可以这样做:
const got = require('got');
function runSequence(url, num) {
let cntr = 0;
let results = [];
return new Promise(function(resolve, reject) {
function checkDone(data) {
++cntr;
results.push(data);
if (cntr < num) {
next();
} else {
resolve(results);
}
}
function next() {
got(url).then(response => {
console.log(response.body);
checkDone(response.body);
}).catch(error => {
console.log(error.response.body);
checkDone(null);
});
}
next();
});
}
runSequence('https://randomuser.me/api/', 10).then(function(results) {
// access array of results here
});
如果 API 调用不必一次执行一个,并且您可以同时将它们全部运行,则可以执行以下操作:
function runParallel(url, num) {
let promises = [];
for (let i = 0; i < num; i++) {
promises.push(got(url));
}
return Promise.all(promises);
}
runParallel('https://randomuser.me/api/', 10).then(function(results) {
// access array of results here
});
注意:并行选项在出现第一个错误时中止,而此处显示的两个序列选项在出现错误时继续。 可以将其更改为其他行为。 您没有指定所需的内容。
下面是运行序列的略有不同的方法:
function runSequence(url, num) {
let cntr = 0;
let results = [];
function checkDone(data) {
++cntr;
results.push(data);
if (cntr < num) {
return next();
} else {
return results;
}
}
function next() {
return got(url).then(response => {
return checkDone(response.body);
}).catch(error => {
return checkDone(null);
});
}
return next();
}
下面是一个通用函数,用于重复某些异步操作 N 次。 您传入异步函数(返回一个 promise),您希望它按顺序重复的次数以及您希望它在出错时继续还是在错误时中止。
// pass a function that returns a promise
function repeatSequence(fn, num, continueOnError) {
let cntr = 0;
let results = [];
checkDone(data) {
++cntr;
results.push(data);
if (cntr < num) {
return next();
} else {
return results;
}
}
function next() {
return fn().then(checkDone).catch(function(err) {
if (continueOnError) {
return checkDone(null);
} else {
// reject on error
throw err;
}
});
}
return next();
}
而且,如果您使用Bluebird Promise库,则可以使用以下Promise.mapSeries()
:
function repeatSequence(fn, num, continueOnError) {
var array = new Array(num);
return Promise.mapSeries(array, function () {
return fn().catch(function (err) {
if (continueOnError) {
return null;
} else {
throw (err);
}
});
});
}
或者,如果您不想要continueOnError
选项,它就会变成这样:
function repeatSequence(fn, num) {
var array = new Array(num);
return Promise.mapSeries(array, fn);
}
我必须同意Bergi的观点,即我们不能将回调与承诺混为一谈。尽管它们都是异步机制,但这两种结构中的每一个在本质上和哲学上都不应被一视同仁。
然而,正如jfriend00指出的那样,主要问题是在每一步中都没有调用"回调"。在使用非承诺库时,这将是正确的解决方案。
溶液
请在下面找到我的修改。本质是:
- 此解决方案是有关如何仅使用 promise 实现它的示例。
-
像 async-q 这样的端口可能会帮助你更好地使用现有库。
const got = require('got'); const async_q = require('async-q'); var tenOperations = []; for(var i = 0; i < 10; i++) { tenOperations.push(doRequest); } function doRequest() { return got('https://randomuser.me/api/') .then(response => { console.log('resp', response.body); return JSON.parse(response.body); }) .catch(error => { console.log('error', error.response.body); return error.response.body; }); } async_q .series(tenOperations) .then (results => { console.log('results', results); }) .done();
相关文章:
- 一个ajax循环有两个输出错误innerHTML
- 在量角器中创建一个.txt错误输出文件是手动的,而不是控制台错误
- Javascript未在其中一个变量上输出0
- 它在另一个函数中嵌套后不会输出文本
- 如何只输出一个SQL结果
- 从一个文本框执行代码,并在另一个文本框中以 HTML 显示输出
- 从引导程序图标十六进制值输出一个符号
- 我有一个mysql的输入文本字段.那么,如何通过ajax从数据库中输出json表呢
- Jquery将最后一个输出作为值
- 将7个图像组合为一个,一个在另一个之上,并输出为单个图像
- rxjs:重置为流,只得到一个输出
- 为什么 async.series 只产生一个输出
- 使用两个文本区域(一个输入和一个输出)和JavaScript创建一个字母排序器
- 在一个输出中针对多个链接定位来自链接的文本值
- 我想使用setInterval()每1秒更新一个输出列表,但它会得到无限循环输出
- angularjs ng在两个级别上重复,但只有一个输出
- 有人能解释一下下面javascript代码的最后一个输出是如何产生的吗
- 多个输入到一个输出
- 需要添加一个输出的图像,一个隐藏的id,和checkout按钮到这个php/ajax脚本和我卡住
- 用于下一个输出的明文