Node.js - 迭代运行带回调的函数

时间:2016-12-06 22:07:23

标签: javascript node.js asynchronous callback

我正在使用node.js

在javascript中开发API

我试图做的是调用一个函数来触发一连串的promises,并且在回调函数中它返回一个包含一个产品信息的数组。

我想要做的是根据需要多次运行此功能,以形成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)将回调中的数据发送回服务器,但是如果我想再次运行此函数并更新数组然后将数组发送到服务器呢?

任何提示的帮助都将非常感激。

1 个答案:

答案 0 :(得分: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
    });
}