Node.js 函数返回未定义?

Node.js Function returning undefined?

尝试使用 XLSX 库在 excel 文件中查找值:

函数有效,它找到了值,但是输出是未定义的,即使调试说找到了值。

函数如下:

var getValsFromExcel = function(sheet,idcol, valcol, val){
  var workbook = new Excel.Workbook(); 
  workbook.xlsx.readFile(__dirname + '/assets/gu.xlsx')
      .then(function() {
          var worksheet = workbook.getWorksheet(sheet);
          worksheet.eachRow({ includeEmpty: false }, function(row, rowNumber) {
            console.log("Row " + rowNumber + " = " + JSON.stringify(row.values));
            console.log(row.values[idcol]);
            console.log('checking ' + row.values[idcol] + ' = ' + val + ' ' + (row.values[idcol] == val))
            if (row.values[idcol] == val){
              console.log('Value found! its ' + row.values[valcol])
              //getValsFromExcel = row.values[valcol];
              return row.values[valcol];
            }
          });
      });
    }  

  var ans = getValsFromExcel('yesno',3, 4, tobj["respondent_consent"]);
  console.log('Q1 answer = ' + ans);

控制台输出如下:

Q1 answer = undefined
Row 1 = [null,"UID","Delete(Y/N)","field: yesno_key_value","field: yesno_display_text"]
field: yesno_key_value
checking field: yesno_key_value = yes false
Row 2 = [null,"5b45fe42f7fe481d8442d5e94b894b45","N","yes","Si"]
yes
checking yes = yes true
Value found! its Si
Row 3 = [null,"b65ba5a1a3814a87b4571e8d477307aa","N","no","No"]
no
checking no = yes false

getValsFromExcel异步,这里更正:

var getValsFromExcel = function(sheet,idcol, valcol, val){
  var workbook = new Excel.Workbook(); 
  return workbook.xlsx.readFile(__dirname + '/assets/gu.xlsx')
  .then(function() {
      var worksheet = workbook.getWorksheet(sheet);
      let answer = null;
      worksheet.eachRow({ includeEmpty: false }, function(row, rowNumber) {
        console.log("Row " + rowNumber + " = " + JSON.stringify(row.values));
        console.log(row.values[idcol]);
        console.log('checking ' + row.values[idcol] + ' = ' + val + ' ' + (row.values[idcol] == val))
        if (row.values[idcol] == val){
          console.log('Value found! its ' + row.values[valcol])
          //getValsFromExcel = row.values[valcol];
          answ = row.values[valcol];
          return;
        }
      });
      return answer;
  });
}  

getValsFromExcel('yesno',3, 4, tobj["respondent_consent"])
.then( answer => console.log('Q1 answer = ' + ans) );

这里发生了几件事。首先,您没有 returning 来自 getValsFromExcel 的任何值,因此 var ans = getValsFromExcel() 将始终未定义(任何函数的默认 return 值)。

但即使你这样做 return workbook.xlsx.readFile(__dirname + '/assets/gu.xlsx').then() // ... 你也不会得到你在 console.log('Value found! its ' + row.values[valcol]) 中的价值,因为 workbook.xlsx.readFile return 是一个承诺。

如果您使用的是最新版本的 Node,您可以在 readFile 调用之前添加 return,然后执行此操作

async function main() {
  var ans = await getValsFromExcel()
  console.log(ans)
}

main()

编辑:很抱歉最初回答了一半。我不喜欢 SO 编辑器,显然我破坏了一个过早保存它的组合键。

这是另一个没有 async/await 的解决方案。请记住:async/await 只是具有特殊语法的 Promises,但它的工作原理是一样的。

getValsFromExcel(/* args */)
  .then((value) => {
    console.log(value)
  })

这是一回事。我们要么必须 await Promise,要么我们必须将一个 then 与一个回调链接在一起,该回调将在 getValsFromExcel 中的 Promise 链中用你 return 的值调用函数。

原始代码中存在许多错误...为了完整起见,这里有进一步的细分:

const Excel = require("exceljs")

var getValsFromExcel = function (sheet, idcol, valcol, val) {
  var workbook = new Excel.Workbook()
  return workbook.xlsx
    .readFile(__dirname + "/assets/gu.xlsx")
    .then(function () {
      var worksheet = workbook.getWorksheet(sheet)
      // let's initialize with some value.
      // undefined would work as well, but we can be explicit if it's not found
      // and make it null.
      let result = null

      worksheet.eachRow({ includeEmpty: false }, function (row, rowNumber) {
        if (row.values[idcol] == val) {
          // ok now we reassign result to the value we want
          result = row.values[valcol]
        }
      })
      // In order to have access to the value in the next `then`
      // of your Promise chain, you _must_ return it.
      return result
    })
    .then((value) => {
      console.log("Value = " + value)
    })
}

// alternate version using async/await

var getValsFromExcel = async function (sheet, idcol, valcol, val) {
  var workbook = new Excel.Workbook()
  // wait for the asynchronous code to resolve
  await workbook.xlsx.readFile(__dirname + "/assets/gu.xlsx")
  // after this point, workbook has been mutated and now contains the file's data

  var worksheet = workbook.getWorksheet(sheet)

  let result = null

  worksheet.eachRow({ includeEmpty: false }, function (row, rowNumber) {
    if (row.values[idcol] == val) {
      result = row.values[valcol]
    }
  })

  console.log("Value = " + result)
}

getValsFromExcel("Sheet1", 2, 2, "Dulce")