Javascript 如何在回调函数中设置新属性,或使用async和await推送到数组?

Javascript 如何在回调函数中设置新属性,或使用async和await推送到数组?,javascript,meteor,vue.js,Javascript,Meteor,Vue.js,当我对rawCollection使用async/await并在循环中获取数据,然后设置新属性(poTmp)时,它会按预期工作。但是在我设置了新的属性和console.log之后,它不会设置新的道具。为什么? let items = await Items.rawCollection() .aggregate([ { $match: match, }, ]) .toArray() let data = items data.

当我对rawCollection使用async/await并在循环中获取数据,然后设置新属性(poTmp)时,它会按预期工作。但是在我设置了新的属性和console.log之后,它不会设置新的道具。为什么?

let items = await Items.rawCollection()
    .aggregate([
      {
        $match: match,
      },
    ])
    .toArray()

  let data = items
  data.forEach(async item => {
    let po = await PurchaseOrderDetails.rawCollection()
      .aggregate([
        {
          $match: {
            itemId: item._id,
            tranDate: { $lte: tDate },
          },
        },
        {
          $group: {
            _id: '$itemId',
            itemDoc: { $last: item },
            onHandPO: { $sum: '$qtyBase' },
          },
        },
        {
          $group: {
            _id: '$itemId',
            itemDoc: { $last: '$itemDoc' },
            lastOnHandPO: { $last: '$onHandPO' },
          },
        },
      ])
      .toArray()
    //==================
    //set new properties
    //==================
    item.poTmp = po[0]

  })
  console.log(data)
  return data
问题在于:

data.forEach(async item => {
异步函数在调用时立即返回承诺,因此forEach完成并转到
控制台.log

此时,委托给异步函数的异步工作尚未完成,因此数据尚未修改

由于您似乎已经使用了异步函数(因为您在代码中使用了wait higher),因此可以使用
wait
Promise.all

Promise.all
需要一个承诺数组,因此我们可以使用
map
来创建承诺数组,而不是
forEach

await Promise.all( data.map(async item => { ...
forEach
类似,
map
将迭代所有项并运行给定函数。与
forEach
不同,
map
将返回包含这些函数结果的数组,如果它们是异步函数,则每个函数都将返回一个承诺

现在,我们使用
Promise.all
创建一个单独的Promise,当每个异步函数都完成时,该Promise将得到解决。我们使用
wait
告诉函数暂停,直到新承诺解决为止

wait
暂停函数意味着console.log在所有异步函数完成之前不会运行,这意味着它在运行时将具有正确的数据。

问题在于:

data.forEach(async item => {
异步函数在调用时立即返回承诺,因此forEach完成并转到
控制台.log

此时,委托给异步函数的异步工作尚未完成,因此数据尚未修改

由于您似乎已经使用了异步函数(因为您在代码中使用了wait higher),因此可以使用
wait
Promise.all

Promise.all
需要一个承诺数组,因此我们可以使用
map
来创建承诺数组,而不是
forEach

await Promise.all( data.map(async item => { ...
forEach
类似,
map
将迭代所有项并运行给定函数。与
forEach
不同,
map
将返回包含这些函数结果的数组,如果它们是异步函数,则每个函数都将返回一个承诺

现在,我们使用
Promise.all
创建一个单独的Promise,当每个异步函数都完成时,该Promise将得到解决。我们使用
wait
告诉函数暂停,直到新承诺解决为止


wait
暂停函数意味着console.log在所有异步函数完成之前不会运行,这意味着它在运行时将具有正确的数据。

以下是一个工作示例,任何需要它的人都可以使用它:

  public async updateBatch(req:any,res:any){

        body = [1,3,4,5,6]

        var rfinal:number[] = [];

        await Promise.all(body.map(async items=>{

            let newStatus = 'MJ';

                inputParameters = [
                { name: 'PID', dataType: sql.Int, value: items },
                { name: 'Status', dataType: sql.VarChar, value: newStatus }
            ];

            let CustomQuery = `UPDATE MYTable 
                SET Status= @Status
                WHERE PID= @PID`;

            const result = await provider.executeQuery(CustomQuery, inputParameters).catch(err => {
                    LogErrors.logErrors(err);
            });
            if(result.rowsAffected[0]>0){
                    rfinal.push(result.rowsAffected[0]);
            }else{
                throw new console.error('Un expected error, updating newsfeed');
            }

        })
        );

  }

下面是一个工作示例,任何需要它的人都可以使用:

  public async updateBatch(req:any,res:any){

        body = [1,3,4,5,6]

        var rfinal:number[] = [];

        await Promise.all(body.map(async items=>{

            let newStatus = 'MJ';

                inputParameters = [
                { name: 'PID', dataType: sql.Int, value: items },
                { name: 'Status', dataType: sql.VarChar, value: newStatus }
            ];

            let CustomQuery = `UPDATE MYTable 
                SET Status= @Status
                WHERE PID= @PID`;

            const result = await provider.executeQuery(CustomQuery, inputParameters).catch(err => {
                    LogErrors.logErrors(err);
            });
            if(result.rowsAffected[0]>0){
                    rfinal.push(result.rowsAffected[0]);
            }else{
                throw new console.error('Un expected error, updating newsfeed');
            }

        })
        );

  }
嘿,弗雷德,你能不能直接说出“等待承诺.all(data.map(aysnc item=>{…”更全面地说?我很难在没有其他代码的情况下遵循你的代码。我问这个问题也不仅仅是因为我想要免费代码,我还试图了解如何解决这个问题。我在另一个网站上看到了Promise.all,我想这可能就是我要找的。嘿,弗雷德,你能马上回答“wait Promise.all(data.map(aysnc item=>{…”更全面地说?我很难在没有其他代码的情况下遵循你的代码。我问这个问题不仅仅是因为我想要免费代码,我还试图了解如何解决这个问题。我在另一个网站上看到了Promise.all,我想这可能就是我要找的。