Array .push 在 Promise 函数中不起作用
Posted
技术标签:
【中文标题】Array .push 在 Promise 函数中不起作用【英文标题】:Array .push is not working inside a promise function 【发布时间】:2017-11-17 08:12:07 【问题描述】:我有一个这样的 nodejs Mongodb 代码。我试图推入一个全局数组并返回我所有的结果,但该数组只包含一个值。知道为什么吗?
var s = [];
var p = function()
return new Promise(function(resolve, reject)
MongoClient.connect(url, function (err, db)
db.listCollections().forEach(function(collname)
db.collection(collname.name).find().sort( duration_in_seconds: 1 ).limit(1).toArray(
function(err, docs)
assert.equal(null, err);
s.push(docs);
resolve();
);
);
);
);
p().then(function()
console.log(s);
);
【问题讨论】:
你不能像这样引用承诺范围之外的变量。而是在“内部”使用它。 Read the duplicate and understand it. 你能解释一下吗?我是新的承诺@NeilLunn @NeilLunn 这里的问题不是承诺,而是forEach
循环
【参考方案1】:
当第一个集合返回其文档时,您正在解决承诺。您需要等待所有这些。而不是将所有内容都包装在一个大的 new Promise
、promisify 每个异步函数中,并让返回的 Promise 实现 with 结果值,而不是将其放入全局变量中:
function connect(url)
return new Promise(function(resolve, reject)
MongoClient.connect(url, function (err, db)
if (err) reject(err);
else resolve(db);
);
);
function getArray(cursor)
return new Promise(function(resolve, reject)
cursor.toArray(function(err, docs)
if (err) reject(err);
else resolve(docs);
);
);
现在您可以使用这些帮助程序编写您的 p
,将每个集合的 Promise 放入一个数组中,然后使用 Promise.all
等待它们,这会为所有结果的数组生成一个 Promise:
function p()
return connect(url).then(function(db)
return getArray(db.listCollections()).then(function(collections)
var promises = collections.map(function(collname)
return getArray(db.collection(collname.name).find().sort(duration_in_seconds: 1 ).limit(1));
);
return Promise.all(promises);
);
);
p().then(function(s)
console.log(s);
);
【讨论】:
非常感谢您的解决方案。我试过了,但我得到了这个错误“TypeError: db.listCollections(...).map is not a function” 天哪,我期待listCollections
返回一个数组(使用标准的forEach
和map
方法),而不是需要等待的异步游标。但我们也可以适应这一点。
哦,是的,我就是这么想的。成功了,谢谢Bergi以上是关于Array .push 在 Promise 函数中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
ReactJS Array.push 函数在 setState 中不起作用
Javascript - 为啥从函数返回 array.push(x) 不会将元素 x 推送到数组中?