我有一个承诺嵌套在另一个看起来像这样的承诺:
adb.screencap(list, id).then(function(missing) {
adb.getScreens(list, id).then(function () {
res.render('screencap', {output: "Screens captured."})
})
})
adb.screencap和adb.getScreens是:
adb.screencap = function(list, id){
return new Promise(function (resolve, reject) {
var array = new Array();
var promises = new Array();
for (var i = 0; i < list.length; i++) {
var cmd = "adb -s " + list[i] + " shell screencap /sdcard/" + list[i] + "-" + id + ".png";
var missing = new Array();
console.log("== " + cmd);
promises.push(adb.openArray(i, array, list, cmd, missing));
}
Promise.all(promises).then(function (missing) {
console.log(("resolve"));
resolve(missing);
})
})
}
adb.getScreens = function(list, id){
return new Promise(function (resolve, reject){
for (var i = 0; i < list.length; i++) {
var cmd = 'adb -s ' + list[i] + ' pull /sdcard/' + list[i] + "-" + id + ".png /home/IdeaProjects/DeviceServer/public/files/" + list[i] + "-" + id + ".png";
exec(cmd, function (err, stdout, stderr) {
console.log(stdout);
console.log(cmd);
});
}
resolve();
})
}
在adb.screencap承诺之前,adb.getScreens承诺是否有任何理由完成?
答案 0 :(得分:1)
我仍在试图弄清楚出了什么问题,因为这似乎很奇怪。 它可能位于openArray()方法或exec()函数中。
对于它的价值,你可以简化一些事情,正如菲利克斯建议的那样:
// If the getScreens handler doesn't need the 'missing' returned from screencap
adb.screencap(list, id).then(function(missing) {
return adb.getScreens(list, id);
}).then(function ( gottenScreens ) {
res.render('screencap', {output: "Screens captured."})
});
// You can just return the Promise.all here instead of adding another promise
// just to resolve the outer one.
adb.screencap = function(list, id) {
var array = new Array();
var promises = new Array();
for (var i = 0; i < list.length; i++) {
var cmd = "adb -s " + list[i] + " shell screencap /sdcard/" + list[i] + "-" + id + ".png";
var missing = new Array();
console.log("== " + cmd);
// is this some async operation or are you just creating all the commands here?
// if so, it does't make sense to use a promise here.
promises.push(adb.openArray(i, array, list, cmd, missing));
}
return Promise.all(promises);
}
答案 1 :(得分:1)
您正在解决getScreens()
内部任何exec()
次来电之前的问题。他们是异步的。他们稍后会完成,但是在你启动它们之后,你就会立即致电resolve()
。因此,在您需要渲染的任何结果可用之前,您最终会尝试渲染。
相反,您需要宣传exec()
本身,然后在数组中收集这些承诺,并使用Promise.all()
查看所有这些承诺何时完成。只有这样才能getScreens()
实际完成。
这里还有很多其他问题。 screencap()
正在使用反模式。这里没有必要创建自己的承诺。您可以从Promise.all()
返回承诺,并且使用此反模式会导致您丢失任何承诺所引发的任何错误。
这是一个建议:
// promisify exec
function execP(cmd) {
return new Promise(function(resolve, reject) {
exec(cmd, function(err, stdout, stderr) {
if (err) return reject(err);
console.log(cmd);
console.log(stdout);
console.log(stderr);
resolve({stdout: stdout, stderr: stderr});
});
});
}
adb.getScreens = function(list, id){
return Promise.all(list.map(function(item) {
var cmd = 'adb -s ' + item + ' pull /sdcard/' + item + "-" + id + ".png /home/IdeaProjects/DeviceServer/public/files/" + item + "-" + id + ".png";
return execP(cmd);
}));
}
现在.getScreens()
会返回一个只有在完成所有exec()
调用后才会解决的承诺(这样您的输出文件就可以使用并为您的redner做好准备)。
这会将.getScreens()
配置为解析为包含所有exec调用中的stdout,stderr信息的对象数组。无论如何,您似乎没有尝试使用该输出,但这是如何配置的。
答案 2 :(得分:0)
您的module.exports = {
context: path.resolve(__dirname, 'src'),
entry: {
main: './main.js'
},
output: {
path: path.resolve(__dirname, './dist'),
publicPath: "/dist",
filename: '[name].js'
},
module: {
rules: [
//...
{
test: /\.(jpg|jpeg|png|svg)$/,
use: [{
loader: 'file-loader?name=[name].[ext]&outputPath=/images/'
}]
},
//...
]
}
};
是否会回复承诺?然后只有adb.openArray
才有效。
如果Promise.all
,你应该在回调中解决getScreens
的承诺。它在外面,不等待exec完成。