使用synchronous request with 的顺序请求
使用Rest Api get方法在1秒内调用settimeout的顺序请求。每次请求数据后按摩并放入数组。现在我想在完成所有请求后得到这个数组。
async function sequentialMF(mfIds) {
var mfData = [];
try {
var timeout = 0;
return await Promise.all(mfIds.map(mfId => {
console.log(mfId)
var options = {
//https://www.quandl.com/api/v3/datasets/AMFI/103504.json?api_key=WfUR65SA5p1PzpBysgK4
method: 'GET',
url: 'https://www.quandl.com/api/v3/datasets/AMFI/' + mfId + '.json',
qs: { api_key: 'WfUR65SA5p1PzpBysgK4' },
};
setTimeout(function () {
request(options, function (error, response, body) {
var obj = JSON.parse(body);
var mfobj = {
"code": obj.dataset.dataset_code,
"name": obj.dataset.name,
"date": obj.dataset.end_date,
"nav": obj.dataset.data[0][1]
}
mfData.push(mfobj);
console.log(obj.dataset.dataset_code + ' ' + obj.dataset.data[0][1]);
console.log('lngth ' + mfData.length + ' ' + mfIds.length)
})
}, timeout);
timeout += 1000;
new Promise(function (resolve, reject) {
if (mfData.length === mfIds.length) {
console.log('testing')
resolve(mfData);
} else reject('errrrrrrrrrrrrror')
})
}))
} catch (err) {
console.log(err)
}
}
而不是map
和Promise.all
使用reduce
和.then
更容易将所有请求序列化为一个结果。您还可以捕获失败请求的任何错误,以便最终得到结果。
//create Fail type instead of rejecting promise
function Fail(details){this.details=details;};
const isFail = item => (item&&item.constructor)===Fail
const sequentialMF = mfIds =>
mfIds.reduce(//reduce ids to one promise
(acc,mfId) =>
acc.then(//acc is the one promise resolving to array of result or Fail items
results => {
var options = {
//https://www.quandl.com/api/v3/datasets/AMFI/103504.json?api_key=WfUR65SA5p1PzpBysgK4
method: 'GET',
url: 'https://www.quandl.com/api/v3/datasets/AMFI/' + mfId + '.json',
qs: { api_key: 'WfUR65SA5p1PzpBysgK4' },
};
return new Promise(//make the request as promise
(resolve,reject)=>
request(options, function (error, response, body) {
if(err){
reject(err);//reject if there is an error
}
var obj = JSON.parse(body);
resolve({//resolve if there is no error
"code": obj.dataset.dataset_code,
"name": obj.dataset.name,
"date": obj.dataset.end_date,
"nav": obj.dataset.data[0][1]
});
})
)
.then(
result=>{//add result item to results if successfull
results.push(result);
return results;
}
)
.catch(
err=>{//add Fail item to results if failed
results.push(new Fail([err,mfId]));
return results;
}
)
.then(
results=>
new Promise(//wait for one second to make the next request
(resolve,reject)=>
setTimeout(
_=>resolve(results)
,1000
)
)
)
}
)
,Promise.resolve([])
)
//example of how to ue this function
sequentialMF(ids)
.then(
results=>{
const successes = results.filter(result=>!isFail(result));
const failed = results.filter(isFail);
}
)