0

为了了解 fetch、promise 和其他 js 内容,我正在尝试编写一个小脚本,该脚本建议从给定的日语文本中学习单词(基于其难度)。

它使用一个名为Kuromojin的日本解析器。

像 Kuromojin 这样的解析器所做的是将短语标记为单词。

例如数据:“日本语が上手ですね!” → 标记词:[{surface_form: 日本语}, {surface_form: が}, {surface_form: 上手}, {surface_form: です}, {surface_form: ね}, {surface_form: !}]

该脚本首先对数据中的单词进行标记,然后使用日语字典的 API (jisho.org) 获取每个标记的单词对应的 JLPT 级别

app.js 文件:

import {  tokenize,  getTokenizer} from "kuromojin";
import {  parseIntoJisho} from "./parseintojisho.js";

const text = "日本語が上手ですね!";
let tokenSet = new Set();

getTokenizer().then(tokenizer => {});

tokenize(text).then(results => { // the result is an array of objects

  results.forEach((token) => {
    tokenSet.add(token.surface_form);
  })

  console.log("======Begin to find JLPT level for below items======");
  tokenSet.forEach((item) => {   
    console.log(item);

    parseIntoJisho(item); // will throw a console log of whichever item's corresponding data is resolved, regardless of item order here, right?
  });
})

parseintojisho.js 文件:

import fetch from 'node-fetch';

/* @param data is string */


export function parseIntoJisho(data) {
  fetch(encodeURI(`https://jisho.org/api/v1/search/words?keyword=${data}`))
    .then(res => res.json())
    .then(jsondata => {
      let JLPTvalueArray = jsondata.data[0].jlpt;

      if (JLPTvalueArray.length) {
        let jlptLevel = JLPTvalueArray.flatMap(str => str.match(/\d+/));
        const max = Math.max(...jlptLevel);
        if (max >= 3) {
          console.log(data + " is of JLPT level N3 or above.")
        } else console.log(data + " is of JLPT level N1 or N2.");
      } else console.log(data + " has no JLPT value.")
    })
    .catch(function(err){
      console.log("No data for " + data);
    })
}

该脚本有效,但不是按顺序显示与每个标记化单词对应的 JLPT 级别,而是随机显示。我猜无论哪个对应的数据首先被解析,都会出现在控制台日志中?

我发现这Promise.All() 可能会解决我的问题,但我找不到正确实施它的方法。

有没有办法将获取的 JLPT 级别按照传入的标记化项目的顺序排列parseIntoJisho(item);

$ node app.js
======Begin to find JLPT level for below items======
日本語
が
上手
です
ね
!

です has no JLPT value. // should be "日本語 has no JLPT value." here instead
No data for ! // should be "が has no JLPT value." here instead
上手 is of JLPT level N3 or above. 
日本語 has no JLPT value. // should be "です has no JLPT value." here instead
ね is of JLPT level N3 or above.
が has no JLPT value. // should be "No data for !" here instead
4

1 回答 1

1

使用.map代替,然后在完成所有异步请求forEach记录结果数组的每个项目。

要将原始字符串传递给异步结果函数,Promise.all请同时使用parseIntoJisho原始数据和原始数据。

Promise.all([...tokenSet].map(parseIntoJisho))
  .then((results) => {
    for (const [data, result] of results) {
      if (!result) continue; // there was an error
      if (result.length) {
        const jlptLevel = result.flatMap(str => str.match(/\d+/));
        const max = Math.max(...jlptLevel);
        if (max >= 3) {
          console.log(data + " is of JLPT level N3 or above.")
        } else console.log(data + " is of JLPT level N1 or N2.");
      } else console.log(data + " has no JLPT value.")
    }
  });
const parseIntoJisho = data => Promise.all([
  data,
  fetch(encodeURI(`https://jisho.org/api/v1/search/words?keyword=${data}`))
    .then(res => res.json())
    .then(jsondata => jsondata.data[0].jlpt)
    .catch(err => null)
]);
于 2021-03-18T15:00:01.777 回答