这是注释的完整代码。
//program purpose:
//list all directories in a given path.
//choose a file and print wether it's a regular file or a directory;
fs = require('fs'); //filesystem
const readline = require('readline-sync');// reads input
var dirPath = readline.question("enter directory path.\n>>> ");
//reads directory with dirPath;
fs.readdir(dirPath,(err,files)=>{
if (err) {
console.log("Oopps there has been an error. ");
console.log(err);
}else {
//prints files in the directory.
for (var i = 0; i < files.length; i++) {
console.log(i+")"+files[i]);
}
//choose a file.
var filePath = readline.question("Choose a file.\n>>> ");
//checks if the choice is a file or directory
fs.stat(dirPath+filePath,(err,stats)=>{
if (err) {
console.log("Oopps there has been an error. ");
console.log(err);
}else {
if (stats.isDirectory()) {
console.log("its a directory.");
//if its a file print its content
}else {
fs.readFile(dirPath+filePath,'utf-8',(err,data)=>{
if (err) {
console.log("Oopps there has been an error. ");
console.log(err);
}
else {
console.log(data);
}
})
}
}
})
}
});
我试图掌握javascript的异步特性,我想重构代码: Code2
问题:第二张图片,readir被文件路径输入打断,我该如何解决,我希望代码看起来不错,并能够递归使用这些功能。
答案 0 :(得分:1)
ES6生成器可以消除回调地狱。 并且还允许您添加 程序流就像循环, 我已将其添加到您的示例中以显示这是多么容易。
我还添加了相应的require()
行,并制作了readline.question
到另一个异步函数中,因此它将作为一个完整的
节点上的示例。
const fs = require("fs");
const readline = require("readline").createInterface({
input: process.stdin,
output: process.stdout
});
function* myGenerator(dirPath) {
const callback = yield;
const [err1, files] = yield fs.readdir(dirPath, callback);
if (err1) {
console.log("Oopps there has been an error. ");
console.log(err1);
return;
}
//prints files in the directory.
for (var i = 0; i < files.length; i++) {
console.log(i + ")" + files[i]);
}
//choose a file.
var filePath;
while (true) {
[filePath] = yield readline.question("Choose a file.\n>>> ", callback);
//checks if the choice is a file or directory
console.log("aaa", dirPath, "bbb", filePath);
const[err2, stats] = yield fs.stat(dirPath + filePath, callback);
if (err2) {
console.log("Oopps there has been an error. Try again.");
console.log(err2);
} else if (stats.isDirectory()) {
console.log("its a directory. Try again");
} else {
break; // OK choice
}
}
// it's a file. Print its content
const [err3, data] = yield fs.readFile(dirPath + filePath, 'utf-8', callback);
if (err3) {
console.log("Oopps there has been an error. ");
console.log(err3);
return;
}
console.log(data);
}
// Create and run the generator
const gen = myGenerator("./"); // Create it
gen.next(); // Start it
gen.next((...args) => gen.next([...args])); // Set its callback function
通过比较,仅靠承诺不能让您使用循环。 异步/等待方法与使用生成器的好处相似 但它要求您将所有异步调用都包装在Promises中。 因此,我发现生成器更容易。
答案 1 :(得分:0)
有几种方法,使用它们可以使其变得简单。
模块化-使每个回调成为独立的函数
承诺-保留异步操作的最终结果。由于它是面向对象的,因此您将获得流畅的界面。因此,通过链接调用方法。
异步/等待-它是#: import CheckBox kivy.uix.checkbox
<ColoredBackground@Image>:
font_size: '48sp'
color: (.9, .5, .4, 1)
canvas.before:
Color:
rgb: (.9, .9, .9)
Rectangle:
pos: self.x + sp(2), self.y + sp(2)
size: self.width - sp(5), self.height - sp(4)
<SampBoxLayout>:
orientation: "vertical"
padding: 10
spacing: 10
# ---------- Button FileChooser ----------
BoxLayout:
orientation: "horizontal"
height: 30
Button:
text: "FileChooser-1"
on_press: root.get_image_one()
Button:
text: "FileChooser-2"
on_press: root.get_image_two()
# ---------- Display Images----------
BoxLayout:
orientation: "horizontal"
height: 30
ColoredBackground:
source: " " # <----------- should be the image file selected by FileChooser-1
size: self.parent.width, self.parent.height
allow_stretch: True
keep_ratio: False
ColoredBackground:
source: " " # <----------- should be the image file selected by FileChooser-2
size: self.parent.width, self.parent.height
allow_stretch: True
keep_ratio: False
的功能实现。它的工作方式与Promise
相同。
这些无效,因为您可以使用名为async的该库