0

我想听听您对TaskEither使用fp-ts或其他函数式编程库进行学习的反馈:

  • Promise在处理nodejs流时使用a Promise,以这种方式使用a是一个好的解决方案吗?最直接的选择是什么?
  • 我正在使用.run().then(...).fold您知道使用我的功能的更简洁的方法吗?
  • 相同的代码可以在Either没有 ? 的情况下重写Promise?你能给我一个样品吗?

export const md5 = (path: string): TaskEither<string, string> => {
  const mkHash = (p: string) =>
    new Promise<string>((resolve, reject) => {
      const hash = createHash("md5");
      const rs = createReadStream(p);
      rs.on("error", (error: Error) => reject(error));
      rs.on("data", chunk => hash.update(chunk));
      rs.on("end", () => {
        return resolve(hash.digest("hex"));
      });
    });
  return tryCatch<string, string>(
    () => mkHash(path).then(x => x),
    message => `cannot create md5 hash: ${message}`
  );
};

it("should return right and create md5 hash for a file", () => {
    md5(fileName)
      .run()
      .then(e =>
        e.fold(console.log, r => {
          expect(r).toBe("SD8ddDad0756a93ded72b823b19dd877");
        })
      );
  });

  it("should return left with an error message", () => {
    md5(BAD_PATH)
      .run()
      .then(e =>
        e.fold(error => expect(error).toContain("ENOENT"), () => ({}))
      );
  });
4

2 回答 2

1

我会使用Fluture这个任务。它是可以包装或生成 Promise 的 Promise 库的 monadic 惰性求值替代方案,但它可以完全单独工作:

export const md5 = path =>
    Future ((reject, resolve) => {
      const hash = createHash ("md5")
      const rs = createReadStream (p)

      rs.on("error", reject);
      rs.on("data", chunk => hash.update (chunk));
      rs.on("end", () => {
        resolve (hash.digest ("hex"));
      })
    })
}

const eventualMd5 = md5('[path]')

Future.fork (console.error) (console.log) (eventualMd5)

基本上,您可以充分Either利用异步流程以及许多相关工具来拆分代码并处理错误和成功场景。

于 2018-10-23T10:47:19.323 回答
0

部分答案:我能够只使用Either没有Promise. 我仍然对替代解决方案非常感兴趣。

export const md5 = (path: string): Either<string, string> => {
  const BUFFER_SIZE = 8192;
  let fd;
  try {
    fd = openSync(path, "r");
    const buffer = Buffer.alloc(BUFFER_SIZE);
    const hash = createHash("md5");
    let bytesRead;
    do {
      bytesRead = readSync(fd, buffer, 0, BUFFER_SIZE, 0);
      hash.update(buffer.slice(0, bytesRead));
    } while (bytesRead === BUFFER_SIZE);
    return right(hash.digest("hex"));
  } catch (error) {
    return left(error.message);
  } finally {
    if (fd !== undefined) {
         closeSync(fd);
    }
  }
};

  it("should return right and create md5 hash for a file", () => {
    const mk = md5(fileName);
    assert.strictEqual(mk.isLeft(), false);
    assert.strictEqual(mk.isRight(), true);
    assert.strictEqual(mk.value, "SS8dd3ad07e6a93ded72b823b19dd877");
  });

  it("should return left return an error message", () => {
    const mk = md5(BAD_PATH);
    assert.strictEqual(mk.isLeft(), true);
    assert.strictEqual(mk.isRight(), false);
    assert.strictEqual(mk.value.includes("ENOENT"), true);
  });
于 2018-10-22T20:24:55.643 回答