Последовательное выполнение Promise.all - PullRequest
0 голосов
/ 25 февраля 2019

Привет! Мне нужно выполнять обещания одно за другим, как мне добиться этого с помощью обещания. Любая помощь будет потрясающей.Ниже приведен пример моего кода, который я сейчас использую, но он выполняется параллельно, поэтому поиск не будет работать должным образом

public testData: any = (req, res) => {
    // This method is called first via API and then promise is triggerd 
    var body = req.body;

    // set up data eg 2 is repeated twice so insert 2, 5 only once into DB
    // Assuming we cant control the data and also maybe 3 maybe inside the DB
    let arrayOfData = [1,2,3,2,4,5,5];

    const promises = arrayOfData.map(this.searchAndInsert.bind(this));

    Promise.all(promises)
        .then((results) => {
            // we only get here if ALL promises fulfill
            console.log('Success', results);
            res.status(200).json({ "status": 1, "message": "Success data" });
        })
        .catch((err) => {
            // Will catch failure of first failed promise
            console.log('Failed:', err);
            res.status(200).json({ "status": 0, "message": "Failed data" });
        });
}

public searchAndInsert: any = (data) => {
    // There are database operations happening here like searching for other
    // entries in the JSON and inserting to DB
    console.log('Searching and updating', data);
    return new Promise((resolve, reject) => {
        // This is not an other function its just written her to make code readable
        if(dataExistsInDB(data) == true){
            resolve(data);
        } else {
            // This is not an other function its just written her to make code readable
            insertIntoDB(data).then() => resolve(data);
        }
    });
}

Я посмотрел в Google и увидел, что сокращение поможет мне. Я был бы признателен за любую помощь в том, какпреобразовать это, чтобы уменьшить или любой другой метод, который вы предлагаете (параллелизм в .map не работает)

1 Ответ

0 голосов
/ 25 февраля 2019

Обещания, к сожалению, не позволяют контролировать их поток.Это означает -> как только вы создадите новое Обещание, оно будет выполнять свои асинхронные части так, как им нравится.

Promise.all не меняет его, его единственная цель состоит в том, чтобы он проверял все обещания, которые вы вставили в негои он разрешается, когда все они завершены (или один из них не работает).

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

async function doAllSequentually(fnPromiseArr) {
  for (let i=0; i < fnPromiseArr.length; i++) {
    const val = await fnPromiseArr[i]();
    console.log(val);
  }
}

function createFnPromise(val) {
  return () => new Promise(resolve => resolve(val));
}

const arr = [];
for (let j=0; j < 10; j++) {
  arr.push(createFnPromise(Math.random()));
}

doAllSequentually(arr).then(() => console.log('finished'));

PS: Это также возможно без асинхронного / ожидающего использования стандартных цепочек обещаний, но его необходимо реализовать с помощью рекурсии.

...