Node.js - функция запуска с обратным вызовом итеративно

Я разрабатываю API в javascript, используя node.js

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

То, что я хочу сделать, - это запустить эту функцию столько раз, сколько требуется для формирования списка продуктов в формате JSON.

Но этот список продуктов должен быть создан до того, как он будет отправлен обратно пользователю, в котором я боюсь.

Это функция, которую я имею:

exports.findProduct = (ingredient, store, callback) => {
            products.getProductData(ingredient, store)
        .then( data => products.getProducts(data))
        .then( productList => products.filterProductData(productList))
        .then( selectedProduct => callback(null,selectedProduct))//get individual products and add to list
        .catch( err => callback(err))
}

Я называю это так

products.findProduct(ingredient, 'Waitrose', (err, data) => {

    if (err) {
        //res.send(status.badRequest, {error: err.message})
    } else {
        res.send(data)
        res.end()
    }

})

res.send(data)Передает данные от обратного вызова обратно на сервер, но что , если я хочу , чтобы запустить эту функцию еще раз и обновить массив , и только затем отправить массив на сервер?

Любая помощь советов будет очень оценена.

javascript,node.js,asynchronous,callback,

0

Ответов: 1


1 принят

Возможная реализация на основе обещаний, позволяющая getAllProducts называть себя рекурсивно.

exports.findProduct = (ingredient, store) => {
    return new Promise((resolve, reject) => {
         products.getProductData(ingredient, store)
        .then( data => products.getProducts(data))
        .then( productList => products.filterProductData(productList))
        .then( selectedProduct => resolve(selectedProduct))
        .catch( err => reject(err))
    }
}



function getAllProducts(ingredientList, shopName) {  
    const allProducts = [];
    return new Promise((resolve, reject) => {
        products.findProducts(ingredientList, shopName)
        .then(product => {
            allProducts.push(...product);

            if(/*need more products*/) {
                getAllProducts(ingredientList, 'Tesco')
                .then(newProducts => {
                    allProducts.push(...newProducts);
                    resolve(allProducts);
                })
                .catch(err => reject(err));
            } else {
                resolve(allProducts);
            }
        })
        .catch(err => reject(err));
    }
}

Называется вот так ...

getAllProducts(ingredientList, 'Waitrose')
.then(products => {
    res.send(products);
    res.end();
}).catch(err => {
    res.send(status.badRequest, {error: err.message});
    res.end();
});

Редактировать:

Вышеупомянутый подход действителен, если вам нужно определить, следует ли делать больше вызовов на основе результата предыдущего вызова. Если вы знаете заранее, что вам нужно сделать несколько вызовов, например, если вы знаете, что хотите проверить Tesco, Waitrose и Asda, тогда есть более простой способ использования Promise.all

exports.findProduct = (ingredient, store) => {
    return new Promise((resolve, reject) => {
         products.getProductData(ingredient, store)
        .then( data => products.getProducts(data))
        .then( productList => products.filterProductData(productList))
        .then( selectedProduct => resolve(selectedProduct))
        .catch( err => reject(err))
    }
}

function makeMultipleCalls() {  
    const stores = ['Waitrose', 'Tesco', 'Asda'];
    const promises = [];

    for (var store in stores) {
        promises.push(product.findProduct(ingredientList, store);
    }

    Promise.all(promises)
    .then(results => {
        res.send(results.reduce((a,b) => a.concat(b)));
        res.end();
    })
    .catch(err => {
        //deal with error
    });
}
JavaScript, Node.js, асинхронный, обратный вызов,
Похожие вопросы