在Array#map()中异步/等待(Node.js,Express)

时间:2019-06-30 16:08:24

标签: javascript node.js express asynchronous async-await

对于Express中的发帖请求,我有以下代码:

app.post('/', urlencodedParser, (req, res) => {
    let value = req.body.value;

    let result = data.map(async (currentObject) => {
        return {
            nodeName: currentObject.nodeName,
            nodeStatus: await lib.checkValue(currentObject.nodeUrl, 
currentObject.nodeName, value)
        };
    });
    console.log(Promise.all(result));

    res.render('list', {data:data, value:value});
})

我通过了异步映射功能。然后,当所有的诺言都返回时,我使用Promise.all获得结果。

但是,Promise.all本身会返回一个承诺Promise { [ Promise { <pending> }, Promise { <pending> } ] }

没有异步,它将返回对象[ { nodeName: currentObject.nodeName, nodeStatus: Promise { <pending> }} ]。我想等我的函数返回并获取nodeStatus

为什么会这样?我想念什么吗?

1 个答案:

答案 0 :(得分:0)

这是因为Promise.all()接受一个Promise数组并返回一个Promise,解析了Promise s并将所有解析的Promise放入数组。另外,我们需要记住,async函数返回一个Promise

您可以尝试运行下面的演示代码段:

let myObj = [
  {
    foo: 'some_value',
    bar: false
  },
  {
    foo: 'some_other_value',
    bar: true
  }
]

function baz(isTrue) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, 100, isTrue ? 'TRUE!' : 'FALSE!')
  })
}

let noAsync = myObj.map(o => {
  return {
    attr1: o.foo,
    attr2: baz(o.bar)
  }
});

let promises = myObj.map(async o => {
  return {
    attr1: o.foo,
    attr2: await baz(o.bar)
  }
});

console.log('No Async :', noAsync);
console.log('Async    :', Promise.all(promises));

Promise.all(promises).then(r => console.log('Promise.then:', r));

PS:运行摘要时,您可能会看到"attr2": {}attr2的对象为空,但是请放心,当在本地计算机上尝试包含Promise { <pending> }