【问题标题】:Write a asynchronous code编写异步代码
【发布时间】:2018-03-24 08:22:16
【问题描述】:

我正在尝试检查服务器上的文件系统以检查文件是否存在。这个简单的问题实际上变成了一项非常具有挑战性的任务。这是我不起作用的基本代码:

  var fs = require('fs');
  var arrayLength = arr.length;
  for (var i = 0; i < arrayLength; i++) {
    var imgfile = arr[i].country
    fs.exists('/var/scraper/public/images/flags' + imgfile + ".png", (exists) => {
      console.log(exists ? 'it\'s there' : 'not here!');
    });                    
  }   

我注意到这不是异步的并且不会起作用。我找到了这个链接: https://nodejs.org/dist/latest-v9.x/docs/api/fs.html#fs_fs_exists_path_callback

我的代码应该是这样构建的。

fs.open('myfile', 'wx', (err, fd) => {
  if (err) {
    if (err.code === 'EEXIST') {
      console.error('myfile already exists');
      return;
    }

    throw err;
  }

  writeMyData(fd);
 });

我希望得到一些帮助来帮助我重写我的代码以使其异步?

对此的任何帮助将不胜感激。

【问题讨论】:

  • 你的意思是“不是异步的,不会工作”?为什么它不起作用?
  • 好吧,当我在 nodejs 中运行它时它不起作用老实说我不知道​​“异步”是什么意思,所以这真的让我的问题变得困难
  • 当我运行我的第一个代码时,它在该目录中找不到任何文件,但是该目录应该是正确的。很长一段时间以来,我一直在努力解决如何使这项工作。
  • 同步代码在 Node.js 中运行良好,通常我们对任何 i/o 使用异步调用。这通常是为了确保资源的有效利用,而不是其他任何事情。

标签: node.js


【解决方案1】:

您可以毫无问题地同步执行此操作,但可能需要一段时间。如果 fs.exists 函数找不到文件,我只需确保您的路径完全正确。我在 /flags 之后添加了一个额外的“/”,因为我假设国家名称数组不包括这个。

const fs = require('fs');
const path = require('path');
const imageDir = '/var/scraper/public/images/flags/';

var filesExist = arr.map((imgObj) => {
  const imgfile = imgObj.country;
  let filePath = path.join(imageDir, imgfile + ".png");
  console.log('Checking existance of file: ', filePath);
  // Return an object with 'exists' property and also the file path
  // To just return the path:
  // return fs.existsSync(filePath) ? filePath: path.join(imageDir, "noimg.png")};
  return { exists: fs.existsSync(filePath), path: fs.existsSync(filePath) ? filePath: path.join(imageDir, "noimg.png")};
});

console.log('Files exist: ', filesExist);

【讨论】:

  • 您好,感谢您的回复。这段代码看起来很有希望。我对此的了解相当低。如果您查看我的帖子#1,我将如何让您的代码循环通过我的数组来检查每个实例?
  • 嘿@Frederik84,我发布的答案将遍历 arr 数组。这就是 arr.map 所做的。它为数组中的每个条目调用 fs.existsSync。 array.map、array.reduce 很强大!
  • 我们随时为您提供帮助!祝你测试顺利。 Node.js 可能有点难学,但它是一项很棒的技术!
  • 没问题!!节点很棒:)
  • 我会更新答案,你只想要路径,对吗?
【解决方案2】:

解决此问题的最简单且耗时的解决方案是简单地使用fs.existsSync 您可以找到该方法的文档here。事实上,如果您查看文档中的 fs.exists,您会注意到至少自上一个 v8 LTS 版本以来,fs.exists 已被弃用(这可能是您遇到问题的原因)。

如果您使用的是支持它的最新版本的节点,那么这是利用 async/await 的绝佳机会。它可能看起来像这样:

const fs = require('fs');
const { promisify } = require('util');
const existsAsync = promisify(fs.exists);

async function checkFiles (arr) {
  const arrayLength = arr.length;

  for (let i = 0; I < arrayLength; I++) {
    const countryName = arr[i].country;

    const filePath = `/var/scraper/public/images/flags${countryName}.png`; 
    const fileExists = await fs.existsAsync(filePath);

    console.log(`File flags${contryName}.png exists: ${fileExists}`);
  }
}

【讨论】:

  • “至少自上一个 v8 LTS 版本以来已被弃用(这可能是您遇到问题的原因)。” - 是的,同步/异步调用让我头晕目眩,哈哈谢谢你的回答我会马上测试它
  • 也作为一个小问题:const 和 var 有什么区别?
  • const 定义了一个不会改变的变量。例如,在使用 require 语句时很有用。
  • 但由于某种原因我无法使此代码工作我收到此错误代码:“意外令牌(-bash:意外令牌附近的语法错误`('”错误从这里开始;异步函数(arr ) { ,我确定是我做错了什么
  • 最终const 会创建一个与分配值的不可变绑定,从而阻止对其进行变异的能力。另一方面,letvar 非常相似,只是let 被限制在块范围内,而var 被限制在整个函数中,而与块范围无关。 Here 是对该主题的更好解释。
猜你喜欢
  • 2017-07-16
  • 1970-01-01
  • 2020-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多