在ES6内部的for循环中,值返回为“未定义”

因此,我目前正在编写清单应用程序,并且在将值插入数据库中时遇到了一些问题。发生的是,我得到了包含有关该特定项目信息的项目对象列表。然后,我将这些项目推送到列表中,并调用一个套接字,该套接字运行for循环以将这些项目插入到我的数据库中,但是当我查看这些项目应位于的表时,它们的所有值都设置为undefined

我的项目对象看起来像这样:

let ItemObject = {
 ID: id,Name: name,Qty: qty
}

调用数据库序列的承诺:

export const insertItem = async (list) => {
    return new Promise(async (resolve,reject) => {
        try {

            console.log(list);

            for(let i = 0; i < list.length; i++){
                const writeSolutionData = `INSERT INTO database (ID,Name,Qty) VALUES ("${list.ID}","${list.Name}","${list.Qty});`;

                const response = await db(writeSolutionData,"Inserting Item");

                resolve(response);   
            }

        } catch (e) {
            console.log("ERROR database.insertItem: " + e);
            reject(e);
        }
    });
};

这是被调用的套接字:

socket.on('insertItem',async (data,callback) => {        
        try {

            const results = await insertItem(data);
            callback(true);

        }
        catch (error) {
            callback(false);
        }
    });

当我在for循环之前控制台记录列表时,我得到了期望的输出,但是在此承诺完成之后,数据库中返回的数据为undefined。我也没有从回调中收到任何错误。 ES6承诺的想法对我来说仍然是新的,如果我在这里所说的不正确,请原谅我。这是我第一次尝试在这样的异步Promise中实现for循环,所以这在第一次就没有用也就不足为奇了。

如果有人对我在做什么错有任何建议,我将不胜感激。谢谢!

cimsimon 回答:在ES6内部的for循环中,值返回为“未定义”

insertItem不必是async函数。只需返回Promise并在承诺回调中使用async,仅在该范围内需要await关键字。

async函数会自动返回一个Promise,但是您需要一个Promise构造函数才能使用resolvereject方法。基本上是同一件事,但是语法和选项不同。

我还注意到您的循环有错误。您尝试从数组中选择list.IDlist.Namelist.Qty,但是应该从数组中的项中获得值。

在查询字符串的末尾,我还发现缺少"

export const insertItem = (list) => new Promise(async (resolve,reject) => {
  try {
    list.forEach(item => {
      const writeSolutionData = `INSERT INTO database (ID,Name,Qty) VALUES ("${item.ID}","${item.Name}","${item.Qty}");`;
      const response = await db(writeSolutionData,"Inserting Item");
      resolve(response);   
    });
  } catch (e) {
    console.log("ERROR database.insertItem: " + e);
    reject(e);
  }
});

附录

使用Promise.all更新了答案。由@wizloc建议。

这将循环您的所有项目并从db()函数返回promise,并将其存储到新数组中。 Promise.all然后将在数组中的所有promise都满足时解析,并在单个数组中返回每个promise的值。

export const insertItem = (list) => new Promise(async (resolve,reject) => {
  try {
    const responses = list.map(item => {
      const writeSolutionData = `INSERT INTO database (ID,"${item.Qty}");`;
      return db(writeSolutionData,"Inserting Item");
    });
    const results = await Promise.all(responses);
    resolve(results);
  } catch (e) {
    console.log("ERROR database.insertItem: " + e);
    reject(e);
  }
});
,

我不熟悉

const writeSolutionData = `INSERT INTO database (ID,Qty) VALUES ("${list.ID}","${list.Name}","${list.Qty}");`;

const response = await db(writeSolutionData,"Inserting Item");

实际上是(除了显而易见的),但是因为db(writeSolutionData,"Inserting Item")是可以等待的,所以它返回了一个承诺。正如我在评论中提到的那样,您的原始代码在循环的第一次迭代中得到解析,因此,如果您需要访问承诺中返回的值,那么您将只能访问第一个值。您问为什么要使用这些值,因为之后只能查询它们,所以我无法回答,因为我对您的项目一无所知,在插入数据后您打算如何处理这些数据,等等。但是许诺的另一个好处是通过链接.then().catch()来进行错误处理。

您可以将整个insertData方法简化为以下

socket.on('insertItem',async (data,callback) => {
    const promises = data.map(x =>
        db(`INSERT INTO database (ID,Qty) VALUES ("${x.ID}","${x.Name}","${x.Qty});`)
    )

    Promise.all(promises)
        .then(values => {
            // Do something with values array
            callback(true)
        })
        .catch(error => {
            // Error handling
            callback(false)
        })
});

以这种方式进行操作将确保仅在成功插入所有项目的情况下才调用callback(true),并且在任何一项失败的情况下都会出错(callback(false))。

,

我认为 public _getListItems() { sp.web.lists.getByTitle("MyList").items.get().then((items: any[]) => { let returnedItems: MyDataModel[] = items.map((item) => { return new MyDataModel(item); }); this.setState({ Items: returnedItems }); }); } 不是异步函数,因为它不包含insertItem ...

await

本文链接:https://www.f2er.com/2717482.html

大家都在问