Javascript Node.js:无法从array.map()返回新数组
我使用一个名为Okrabyte的包从文件夹中的每个图像文件中提取单词。结果应该是一个新的数组,其中包含可以在其他函数中使用的提取文本 当我运行此命令时:Javascript Node.js:无法从array.map()返回新数组,javascript,arrays,node.js,async-await,fs,Javascript,Arrays,Node.js,Async Await,Fs,我使用一个名为Okrabyte的包从文件夹中的每个图像文件中提取单词。结果应该是一个新的数组,其中包含可以在其他函数中使用的提取文本 当我运行此命令时: var fs = require("fs"); var okrabyte = require("okrabyte"); fs.readdir("imgs/", function(err, files){ files.map((file)=>{ okrabyte.decodeBuffer(fs.readFileSync("i
var fs = require("fs");
var okrabyte = require("okrabyte");
fs.readdir("imgs/", function(err, files){
files.map((file)=>{
okrabyte.decodeBuffer(fs.readFileSync("imgs/"+ file), (err, data)=>{
let splitWords = data.split(" ");
let word = splitWords[0].substr(1);
console.log(word);
})
})
})
控制台记录每个单词。要返回包含这些单词的数组,我尝试了以下操作:
async function words() {
await fs.readdir("imgs/", function (err, files) {
return files.map(async (file) => {
await okrabyte.decodeBuffer(fs.readFileSync("imgs/" + file), async (err, data) => {
let splitWords = data.split(" ");
let word = splitWords[0].substr(1);
return word
})
})
})
}
var testing = await words();
console.log(testing);
这给了
未定义的我尝试过将所有内容都转换为承诺,我尝试过异步等待,我尝试过将每个单词放入一个新数组并以闭包方式返回该数组,但没有任何效果-我做错了什么???如果你的map函数是异步的,那么它返回的是承诺,因此,映射数组实际上是一个承诺数组。但是您可以使用Promise.all
来获得该数组的解析值
此外,您正在尝试等待调用fs.readdir
和okrabyte.decodeBuffer
,这两个函数都接受回调,并且不返回承诺。因此,如果您想在那里使用承诺,您必须手动将它们包装在承诺构造函数中
我会这样做:
async function words() {
// Wrap `fs` call into a promise, so we can await it:
const files = await new Promise((resolve, reject) => {
fs.readdir("imgs/", (err, files) => { err ? reject(err) : resolve(files); });
});
// Since map function returns a promise, we wrap into a Promise.all:
const mapped = await Promise.all(files.map((file) => {
// Wrap okrabyte.decodeBuffer into promise, and return it:
return new Promise((resolve, reject) => {
okrabyte.decodeBuffer(fs.readFileSync("imgs/" + file), (err, data) => {
if (err) return reject(err);
const splitWords = data.split(" ");
const word = splitWords[0].substr(1);
resolve(word);
})
})
}))
// Mapped is now an array containing each "word".
return mapped;
}
var testing = await words();
// Should now log your array of words correctly.
console.log(testing);
如果映射函数是异步的,那么它将返回一个承诺,因此映射数组实际上是一个承诺数组。但是您可以使用Promise.all
来获得该数组的解析值
此外,您正在尝试等待调用fs.readdir
和okrabyte.decodeBuffer
,这两个函数都接受回调,并且不返回承诺。因此,如果您想在那里使用承诺,您必须手动将它们包装在承诺构造函数中
我会这样做:
async function words() {
// Wrap `fs` call into a promise, so we can await it:
const files = await new Promise((resolve, reject) => {
fs.readdir("imgs/", (err, files) => { err ? reject(err) : resolve(files); });
});
// Since map function returns a promise, we wrap into a Promise.all:
const mapped = await Promise.all(files.map((file) => {
// Wrap okrabyte.decodeBuffer into promise, and return it:
return new Promise((resolve, reject) => {
okrabyte.decodeBuffer(fs.readFileSync("imgs/" + file), (err, data) => {
if (err) return reject(err);
const splitWords = data.split(" ");
const word = splitWords[0].substr(1);
resolve(word);
})
})
}))
// Mapped is now an array containing each "word".
return mapped;
}
var testing = await words();
// Should now log your array of words correctly.
console.log(testing);
您将单词值返回到包含的函数,但不是map()函数
希望此代码对您有所帮助
async function words() {
global.words = [];
await fs.readdir("imgs/", function(err, files){
return files.map( async(file)=>{
await okrabyte.decodeBuffer(fs.readFileSync("imgs/"+ file), async (err, data)=>{
let splitWords = data.split(" ");
let word = splitWords[0].substr(1);
global.words.push(word);
})
})
})
}
var testing = await words();
testing = global.words;
console.log(testing);
您将单词值返回到包含的函数,但不是map()函数
希望此代码对您有所帮助
async function words() {
global.words = [];
await fs.readdir("imgs/", function(err, files){
return files.map( async(file)=>{
await okrabyte.decodeBuffer(fs.readFileSync("imgs/"+ file), async (err, data)=>{
let splitWords = data.split(" ");
let word = splitWords[0].substr(1);
global.words.push(word);
})
})
})
}
var testing = await words();
testing = global.words;
console.log(testing);
您不应该以这种方式使用异步等待。当你处理承诺时,应该使用这一点。库okrabyte使用回调的概念
我建议您遵循以下方法:
(1) 将okrabyte.decodeBuffer部分包含在一个函数中,该函数返回在回调中解析的承诺
(2) 使用files.map生成一个承诺数组,以调用(1)中定义的函数
(3) 使用Promise.all等待所有承诺执行并完成,然后再继续处理所有单词
演练:
第1部分
const processWord = (file) => {
return new Promise((resolve, reject) => {
okrabyte.decodeBuffer(fs.readFileSync("imgs/"+ file), (err, data)=>{
if (err) {
reject(err); // <--- reject the promise if there was an error
return;
}
let splitWords = data.split(" ");
let word = splitWords[0].substr(1);
resolve(word); // <--- resolve the promise with the word
})
});
}
上述内容将产生一系列承诺
第三部分
fs.readdir("imgs/", function(err, files){
const promises = files.map((file)=>{
return processWord(file);
})
Promise.all(promises)
.then(responses => {
// responses holds a list of words
// You will get each word accessing responses[0], responses[1], responses[2], ...
console.log(responses);
})
.catch(error => {
console.log(error); // Deal with the error in some way
});
})
上面使用Promise.all在转到then()块之前等待所有承诺的解析,假设没有发生错误
您可以在一个方法中进一步隔离上面的构造,该方法将返回一个包含所有单词列表的承诺,其方式与第1部分的processWord函数中的方式大致相同。这样,如果愿意,您最终可以使用async Wait,而不是在then()块中处理事情:
您不应该以这种方式使用异步等待。当你处理承诺时,应该使用这一点。库okrabyte使用回调的概念
我建议您遵循以下方法:
(1) 将okrabyte.decodeBuffer部分包含在一个函数中,该函数返回在回调中解析的承诺
(2) 使用files.map生成一个承诺数组,以调用(1)中定义的函数
(3) 使用Promise.all等待所有承诺执行并完成,然后再继续处理所有单词
演练:
第1部分
const processWord = (file) => {
return new Promise((resolve, reject) => {
okrabyte.decodeBuffer(fs.readFileSync("imgs/"+ file), (err, data)=>{
if (err) {
reject(err); // <--- reject the promise if there was an error
return;
}
let splitWords = data.split(" ");
let word = splitWords[0].substr(1);
resolve(word); // <--- resolve the promise with the word
})
});
}
上述内容将产生一系列承诺
第三部分
fs.readdir("imgs/", function(err, files){
const promises = files.map((file)=>{
return processWord(file);
})
Promise.all(promises)
.then(responses => {
// responses holds a list of words
// You will get each word accessing responses[0], responses[1], responses[2], ...
console.log(responses);
})
.catch(error => {
console.log(error); // Deal with the error in some way
});
})
上面使用Promise.all在转到then()块之前等待所有承诺的解析,假设没有发生错误
您可以在一个方法中进一步隔离上面的构造,该方法将返回一个包含所有单词列表的承诺,其方式与第1部分的processWord函数中的方式大致相同。这样,如果愿意,您最终可以使用async Wait,而不是在then()块中处理事情:
看似足够简洁的狂热解决方案/解释-谢谢!看似足够简洁的狂热解决方案/解释-谢谢!这也是一个非常棒的演练,谢谢!我选择另一个答案是因为它简单明了。这也是一个非常好的演练谢谢!我选择了另一个答案,因为它简单明了。不幸的是,这不起作用,因为我们使用的是map(),所以我想利用map()生成的数组,而不是创建一个额外的数组并将元素推送到其中。不幸的是,这不起作用,因为我们使用的是map(),所以我想利用map()生成的数组而不是创建一个额外的数组并将元素推送到它。