如何在Node.js中从API同步获取?

时间:2018-08-04 07:14:43

标签: javascript node.js ecmascript-6 promise fetch-api

TLDR:如何使用ES6提取来同步下载

我正在尝试在Node中编写脚本以从API下载数据,直到没有其他要下载的内容,例如端点的数据集大小约为12000,但每个呼叫仅提供100,我需要所有数据。因此,我决定同步下载它,只有在返回的json最终为空时才停止下载。

// function to make one api GET call
getData = (offset) => {
  return fetch('http://...'+'?start=' + offset)
    .then(...)
}

// make api calls until json is finally empty, 
// indicating that I've downloaded all the data
offset = 0
const results = getData(offset)
while (results.length != 0) {
  // combine results...
  i += 100 // move offset
  results = getData(i)
}

因为我不知道确切的数据量和结束的偏移量,是否再打一次电话取决于最后一个。

上面的代码失败,因为getData()的承诺不能及时地为while循环解析。用另一种语言,因为getData阻塞直到完成才可以。我尝试过await getData,但是它必须放在async中(我不知道要放在哪里,我已经有了承诺)。有什么方法可以强制getData()阻止直到解决?

2 个答案:

答案 0 :(得分:0)

您可以将getData()函数标记为async

async getData() {
  return fetch('http://...'+'?start=' + offset)
    .then(...)
}

然后await进行返回的承诺完成

await const results = getData(offset)

或者您可以修改代码以处理是否在promise回调中进行另一个调用的逻辑。像

function fetchData(offset) {
  if (offset < 1000) {
    return Promise.resolve([1,2,3].map(i=>offset+i));
  } else {
    return Promise.resolve([]);
  }
}

function needsMoreData(results) {
  return results.length > 0;
}

function fetchNextDataIfNeeded(results, offset) {
  if (needsMoreData(results)) {
    return fetchRemainingData(offset + 100)
     .then(nextResults=>[...results, ...nextResults]);
  }
  return Promise.resolve(results);
}

function fetchRemainingData( offset) {
  return fetchData(offset)
      .then(results=>fetchNextDataIfNeeded(results, offset));
}


function fetchAllData() {
  return fetchRemainingData(0)
   .then(results=>console.log(results));
}

fetchAllData();

请参见https://jsfiddle.net/rwycbn5q/1/

答案 1 :(得分:0)

我最近发现自己处于类似情况,但是某些功能无法同步进行。但是您可以执行以下操作:

@[@"1",@"2",@"4",@"4",@"4",@"2"] .