异步 node.js:带有回调的嵌套数组

Posted

技术标签:

【中文标题】异步 node.js:带有回调的嵌套数组【英文标题】:Async node.js :nested array with callback 【发布时间】:2018-06-27 07:40:03 【问题描述】:

我有一个这样的数组

var products = [
            'id':1 ,items:['a','b'],
            'id':2,items:['c','d']
           ]

我想要的是遍历这个数组并为items数组插入数据库

例如没有异步

products.forEach((pdct) =>

    pdct.items.forEach((item) => 
           calltoDb(item,function(result)
               console.log(item+'item inserted');
             )       
       );

);

我希望async 也能达到同样的效果,并在插入所有项目后得到结果

我需要使用哪个eacheachSeries 方法我对此感到困惑

【问题讨论】:

你需要并行运行calltodb还是一个接一个? @zabusa calltodb 一一不并行 您可以使用await Promise.all 以干净的方式实现此目的,而无需使用 caolan 异步模块。 【参考方案1】:

如果您承诺该回调,您可以使用Promise.all 非常简单地做到这一点,它包装了一个 Promise 数组,并在数组中的每个 Promise 解析后解析。

Promise.all(products.map(product => 
    return Promise.all(product.items.map(item => 
        return new Promise(resolve => 
            calltoDb(item, resolve)
        )
    ))
)).then(results => 
    console.log(results)  // item results are in a nested array:
                          //     [['a','b'],
                          //      ['c', 'd']]
)

如果您使用的是 Node 8,您也可以去掉 .then 并改用 await 关键字:

const results = await Promise.all(products.map(product => 
    return Promise.all(product.items.map(item => 
        return new Promise(resolve => 
            calltoDb(item, resolve)
        )
    ))
))

【讨论】:

【参考方案2】:

您不必使用外部库在 javascript 中执行同步 for 循环,只需使用 async/await 语法即可

看看这段代码,它会一一插入你的记录,等待每一个完成,直到跳转到下一个。

async function insert() 
    var all_results = []
    for (var pdct of products) 
        for (var item of pdct.items) 
            var result = await new Promise(next => 
                calltoDb(item, res => next(res))
            )
            all_results.push(result)
        
    
    return all_results


insert().then(results => 
    console.log('Here u have all results', results)
) 

【讨论】:

【参考方案3】:

eacheachSeries 之间的区别在于 eachSeries 一次运行一个异步操作。所以对于each,不能保证迭代函数会按顺序完成。

所以如果你不需要像 iteratee 这样的订单最好使用each,否则使用eachSeries

例子:

import each from 'async/each'
let products = [
   'id':1 ,items:['a','b']
   , 'id':2, items:['c','d']
   , 'id':3, items:['e','f']
]
each(products, (product, callback) => 
   console.log(product)
   return callback()
)

可以返回

'id':3, items:['e','f']
'id':1 ,items:['a','b']
'id':2, items:['c','d']

每个系列:

import eachSeries from 'async/eachSeries'
let products = [
   'id':1 ,items:['a','b']
   , 'id':2, items:['c','d']
   , 'id':3, items:['e','f']
]
eachSeries(products, (product, callback) => 
   console.log(product)
   return callback()
)

它会返回

'id':1 ,items:['a','b']
'id':2, items:['c','d']
'id':3, items:['e','f']

【讨论】:

你能举一个当前场景的例子 @iambatman 我也更新了我的示例。但它会像我之前展示的那样以相同的方式工作。 eachSeries 将按照您在数组中提供的顺序循环数组。每个不保证与数组中的顺序相同。

以上是关于异步 node.js:带有回调的嵌套数组的主要内容,如果未能解决你的问题,请参考以下文章

在 Node.js 中异步添加到数组

Node.js-串行化流程控制

node.js异步回调

Node.js 入门教程 :API-准备知识

5Node.js 回调函数

Node.js 探秘 - 求异存同