【发布时间】:2016-10-14 13:47:23
【问题描述】:
我的问题是我不知道如何知道动态承诺数组何时解决了所有承诺。
这里是一个例子:
var promiseArray = [];
promiseArray.push(new Promise(){/*blablabla*/});
promiseArray.push(new Promise(){/*blablabla*/});
Promise.all(promiseArray).then(function(){
// This will be executen when those 2 promises are solved.
});
promiseArray.push(new Promise(){/*blablabla*/});
我这里有问题。 Promise.all 行为将在前 2 个 Promise 解决时执行,但是在这 2 个 Promise 解决之前,添加第三个 Promise 并且不会考虑这个新的 Promise。
所以,我需要的是这样说:“嘿Promise.all,你有一个动态数组要检查”。我该怎么做?
请记住,这只是一个示例。我知道我可以将行 Promise.all 移动到最后一行,但实际上新的 Promise 是在解决另一个 Promise 时动态添加的,并且新的 Promise 也可以添加新的 Promise,所以它是一个真正的动态数组。
我的真实用例是这样的:
- 我使用 Twitter API 检查是否有新推文(使用 Search Api)。
- 如果我发现新的推文,我会将其添加到 MongoDB(这里我们有 Promises)。
- 如果这些新推文与我的 MongoDB 中没有的用户相关(这里我们有新的承诺,因为我必须去 MongoDB 检查我是否有那个用户),我们去 Twitter API获取用户信息(更多承诺),然后我们将这些新用户添加到 MongoDB(是的,更多承诺)。
- 然后,我去 MongoDB 插入新值以将新推文与这些新用户相关联(更多承诺!wiii!)。
- 当对 MongoDB 的所有查询都已解决(所有选择、更新、插入)时,关闭 MongoDB 连接。
另一个困难的例子:
var allPromises = [];
allPromises.push(new Promise(function(done, fail){
mongoDB.connect(function(error){
//Because mongoDB works with callbacks instead of promises
if(error)
fail();
else
ajax.get('/whatever').then(function(){
if (somethingHappens) {
allPromises.push(new Promise(function(done, fail){ //This promise never will be take in account
// bla bla bla
if (somethingHappens) {
allPromises.push(new Promise(function(done, fail){ //This promise never will be take in account
// bla bla bla
}));
} else {
ajax.get('/whatever/2').then(function(){
if (somethingHappens) {
allPromises.push(new Promise(function(done, fail){ //This promise never will be take in account
// bla bla bla
}));
}
});
}
}));
} else {
ajax.get('/whatever/2').then(function(){
if (somethingHappens) {
allPromises.push(new Promise(function(done, fail){ //This promise never will be take in account
// bla bla bla
if (somethingHappens) {
allPromises.push(new Promise(function(done, fail){ //This promise never will be take in account
// bla bla bla
}));
} else {
ajax.get('/whatever/2').then(function(){
if (somethingHappens) {
allPromises.push(new Promise(function(done, fail){ //This promise never will be take in account
// bla bla bla
}));
}
});
}
}));
}
});
}
});
});
}));
Promise.all(allPromises).then(function(){
// Soooo, all work is done!
mongodb.close()!
});
所以,现在,一个美丽的例子。当调用最后一个(我们不知道哪个是最后一个)promise 时,我们需要调用 showAllTheInformation 函数。你是怎么做到的?:
var name = 'anonimus';
var date = 'we do not know';
function userClikOnLogIn() {
$http.get('/login/user/password').then(function(data){
if (data.logguedOk) {
$http.get('/checkIfIsAdmin').then(function(data){
if (data.yesHeIsAnAdmin) {
$http.get('/getTheNameOfTheUser').then(function(data){
if(data.userHasName) {
$http.get('/getCurrentDate').then(function(data){
currentDate = data.theNewCurrentDate;
});
}
});
}
});
}
});
}
function showAllTheInformation() {
alert('Hi ' + name + ' today is:' + date);
}
这里是另一个具有更多上下文的示例: https://jsfiddle.net/f0a1s79o/2/
【问题讨论】:
-
动态添加 Promise 的用例是什么?
-
@Bergi 我刚刚添加了有关用例的更多信息
-
使用问题中描述的步骤 1-5 有什么问题?
-
@guest271314 因为我有 300 个 forEach 添加 300 个承诺,当它们解决时可能会再添加 300 个承诺或可能不添加。所以你不知道谁以及何时添加了数组中的最后一个承诺。所以你不知道什么时候应该调用 Promise.all
-
@NoelBroda 无论是一、二还是三百个承诺都无关紧要。如果流程需要五个步骤,则在第 5 步完成时将
Promise返回到Promise.all()内的可迭代对象。
标签: javascript promise ecmascript-6