-1

sequential request with synchronous request with

Using Rest Api get method called sequential request of settimeout on 1 sec. after each request data massaging and put in array. Now I would like to get this array after all request were done.

       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)
        }
    }
  • This could be of help: https://stackoverflow.com/questions/34436129/how-to-iterate-an-array-synchronously-using-lodash-or-underscore – Nidhin David Dec 24 '17 at 07:07

1 Answers1

0

Instead of map and Promise.all it's easier to use reduce and .then to serialize all the request to one result. You can also catch any errors for failed requests so you'll get the result in the end.

//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);
  }
)
HMR
  • 37,593
  • 24
  • 91
  • 160