我是节点的新手,我遇到了解决异步Promise的问题。我的承诺没有解决,我不确定我做错了什么。我仍然无法理解承诺和回调,所以任何反馈都是有帮助的。
m.index = ... # same index with first model's m.index
m.y = Var(m.index) # lets assume it has values or I can put with init command
答案 0 :(得分:2)
至少看到三个错误:
当您点击此if
语句if(! /^\..*/.test(file)){
并且它未执行if
块时,父承诺永远不会解决。
fs.stat()
上没有错误处理,因此如果您在该通话中收到错误,则忽略该错误并尝试使用错误值。
您拨打fs.readdir()
时的错误处理不完整,并且会给您一个永不解决的承诺(当它应该被拒绝时)。
对于强大的解决方案,您真的不希望在同一代码中混合使用promises和callback。它会导致很多错误,特别是错误处理(因为你可以看到你至少有三个错误 - 其中两个错误处理)。
如果您打算使用Promises,那么请宣传您在最低级别使用的异步操作,并仅使用promises来控制异步代码流。我所知道的最简单的方法是宣传相关的fs
操作,就是使用Bluebird promise库及其Promise.promisifyAll()
。您不必使用该库。您可以为您正在使用的异步操作手动编写promise包装器。
以下是使用Bluebird promise库的代码版本:
const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));
function filterFiles() {
return fs.readdirAsync(rootDir).then(function(files) {
let fileArray = [];
let dirArray = [];
// filter out entries that start with .
files = files.filter(function(f) {
return !f.startsWith(".");
});
return Promise.map(files, function(f) {
return fs.statAsync(f).then(function(stats) {
if (stats.isDirectory()) {
dirArray.push(f);
} else {
fileArray.push(f);
}
});
}).then(function() {
// make the resolved value be an object with two properties containing the arrays
return {dirArray, fileArray};
});
});
}
filterFiles().then(function(data) {
res.json(data);
}).catch(function(err) {
// put whatever is appropriate here
res.status(500).end();
});
通过以下更改重写/重组:
.
开头的文件(简化异步处理)。Promise.map()
并行处理值数组。filterFiles().then()
处理程序中,处理错误res.send()
一个Javascript对象,所以我使用res.json(data)
代替(虽然我不确定你到底想要发送什么)。.startsWith()
替换正则表达式比较。如果您不想使用Bluebird promise库,您可以为您使用的fs方法创建自己的promise包装器:
fs.readdirAsync = function(dir) {
return new Promise(function(resolve, reject) {
fs.readdir(dir, function(err, data) {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
fs.statAsync = function(f) {
return new Promise(function(resolve, reject) {
fs.stat(f, function(err, data) {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
function filterFiles() {
return fs.readdirAsync(rootDir).then(function(files) {
let fileArray = [];
let dirArray = [];
// filter out entries that start with .
files = files.filter(function(f) {
return !f.startsWith(".");
});
return Promise.all(files.map(function(f) {
return fs.statAsync(f).then(function(stats) {
if (stats.isDirectory()) {
dirArray.push(f);
} else {
fileArray.push(f);
}
});
})).then(function() {
// make the resolved value be an object with two properties containing the arrays
return {dirArray, fileArray};
});
});
}
filterFiles().then(function(data) {
res.json(data);
}).catch(function(err) {
res.status(500).end();
});
答案 1 :(得分:0)
您遇到的主要问题是最外层的承诺未得到解决或拒绝。您可以通过解析Promise.all
而非退回来解决此问题。
resolve(
Promise.all(actions)
.then(function(resolvedTasks){
// ... next potential issue is here
return {dirArray: dirArray, fileArray: fileArray}
})
);
(我知道,有点尴尬吗?)
接下来,Promise.all解析后的返回值有点奇怪。在task
功能中,您将项目推送到dirArray
和fileArray
,但不会在您的代码段中声明或分配这些项目。我将假设它们是此代码的范围。在这种情况下,您只需要返回所需的对象。
此外,为了使您的异步代码更具可读性,请参阅以下提示: