Как я могу использовать циклы / рекурсию с цепочками обещаний? - PullRequest
0 голосов
/ 11 ноября 2018

Представьте, например, что вы хотите сохранить разбитые на страницы данные из API в базе данных.

let db;
let pageitems = 35
var offset = 0;

dbConnect //establish connection to database 
  .then( fetch(apiLink+?offset=2) 
  .then( res => res.json())
  .then( res => {
     var total = res.count
     return collection.insertMany(res.data, {ordered: false})
     // If offset is less than total, I want to increase offset and go back to the fetch-event.
  .catch( err => {
    if(err.code !== 11000){log(err)}
    else{log({completed: err.result.nInserted, duplicates: 
    err.result.result.writeErrors.length});}
  })
  .then(() => {
    connection.close();
  })

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

Вы можете просто использовать обычный цикл:

 (async function() {
    const conn = await dbConnect;
    for(let offset = 0; true; offset++) { 
      const { data, count } = await (await fetch(`api?page=${offset}`)).json();
      // Exit if the page is empty
      if(count === 0) break;
      await collection.insertMany(data, { ordered: false });
    }
 })();

Чтобы ускорить это, вы можете выполнять несколько запросов параллельно:

 const chunkSize = 10; // 10 in parallel
 for(let offset = 0; offset < chunkSize; offset++) {
   (async function() {
      const conn = await dbConnect;
      for(let offset2 = 0; true; offset2 += chunkSize) { 
        const { data, count } = await (await fetch(`api?page=${offset + offset2}`)).json();
        // Exit if the page is empty
        if(count === 0) break;
        await collection.insertMany(data, { ordered: false });
      }
   })();
 }
0 голосов
/ 11 ноября 2018

По сути, вы захотите обернуть ваш выбор и вставить в функцию, которую вы будете вызывать много раз. Ниже приведен пример, иллюстрирующий мою точку зрения ...

let db;
let pageitems = 35
var offset = 0;


var db = dbConnect() //establish connection to database 

function fetch_and_insert(offset) {
    db
    .then(fetch(apiLink + "?" + offset))
    .then(res => res.json())
    .then(res => {
        var total = res.count
        collection.insertMany(res.data, { ordered: false })
        .catch(err => {
            if (err.code !== 11000) { log(err) }
            else {
                log({
                    completed: err.result.nInserted, duplicates: err.result.result.writeErrors.length
                });
            }
        })
        if (offset < total) return fetch_and_insert(offset + pageitems)
        return null;
    })
}

fetch_and_insert(offset)
.then(() => {
    connection.close();
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...