Javascript 返回为';未定义';ES6承诺内的for循环

Javascript 返回为';未定义';ES6承诺内的for循环,javascript,socket.io,es6-promise,Javascript,Socket.io,Es6 Promise,因此,我目前正在编写一个清单应用程序,在将值插入数据库时遇到了一些问题。所发生的事情是,我得到了一个item对象列表,其中包含关于特定项的信息。然后,我将这些项目推送到一个列表中,并调用一个运行for循环的套接字将这些项目插入到我的数据库中,但是当我查看这些项目应该位于的表时,它们的所有值都被设置为未定义的 “我的项目”对象如下所示: let ItemObject = { ID: id, Name: name, Qty: qty } 调用DB序列的承诺: export const ins

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

“我的项目”对象如下所示:

let ItemObject = {
 ID: id,
 Name: name,
 Qty: qty
}
调用DB序列的承诺:

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);
        }
    });
};

当我在for循环之前记录列表时,我得到了预期的输出,但是在这个承诺完成之后,在我的数据库中返回的数据是未定义的。我也没有收到来自回调的错误。ES6承诺的想法对我来说仍然是新的,所以如果我这里的想法不正确,请原谅我。这是我第一次尝试在这样一个异步承诺中实现for循环,所以第一次这样做不起作用对我来说并不奇怪


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

我认为
insertItem
不是一个异步函数,因为它不包含
wait

export const insertItem=/*异步{
返回新承诺(异步(解析、拒绝)=>{
试一试{
控制台日志(列表);
for(设i=0;i}
我认为
insertItem
不是一个异步函数,因为它不包含
wait

export const insertItem=/*异步{
返回新承诺(异步(解析、拒绝)=>{
试一试{
控制台日志(列表);
for(设i=0;i};插入项
不必是
异步
函数。只需返回
Promise
并使用
async
Promise回调,仅在该范围内需要
wait
关键字

async
函数会自动返回一个
Promise
,但您需要一个
Promise
构造函数来使用
resolve
reject
方法。它基本上是一样的,但是有不同的语法和选项

我还注意到你的循环有一个错误。您尝试从数组中选择
list.ID
list.Name
list.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);
  }
});
补遗 使用@wizloc建议的
Promise.all
更新了答案

这将循环所有项目,并从
db()
函数返回承诺,并将它们存储到新数组中。
Promise。然后,只要数组中的所有承诺都已满,所有
都将解析,并返回单个数组中每个承诺的值

export const insertItem = (list) => new Promise(async (resolve, reject) => {
  try {
    const responses = list.map(item => {
      const writeSolutionData = `INSERT INTO database (ID, Name, Qty) VALUES ("${item.ID}", "${item.Name}", "${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);
  }
});

insertItem
不必是
async
函数。只需返回
Promise
并使用
async
将其作为Promise回调,仅在该范围内需要
wait
关键字

async
函数自动返回一个
Promise
,但是您需要一个
Promise
构造函数来使用
resolve
reject
方法。这基本上是一样的,但语法和选项不同

我还注意到您的循环有一个错误。您尝试从数组中选择
list.ID
list.Name
list.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.all
将在数组中的所有承诺都已满时解析,并返回单个数组中每个承诺的值

export const insertItem = (list) => new Promise(async (resolve, reject) => {
  try {
    const responses = list.map(item => {
      const writeSolutionData = `INSERT INTO database (ID, Name, Qty) VALUES ("${item.ID}", "${item.Name}", "${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, Name, 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, Name, 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)
        })
});
这样做将确保只有在成功插入所有项时才会调用
回调(true)