Bro*_*oel 11 javascript promise ecmascript-6
我的问题是我不知道如何知道动态promise数组何时解决了所有的promise.
这是一个例子:
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*/});
Run Code Online (Sandbox Code Playgroud)
我这里有问题.当前Promise.all两个承诺被解决时,行为将被执行,但是,在这两个承诺被解决之前,第三个承诺被添加并且这个新承诺将不被考虑.
所以,我需要的是:"嘿Promise.all,你有一个动态数组来检查".我该怎么做?
请记住,这只是一个例子.我知道我可以将线Promise.all移到最后一行,但实际上新的承诺是在另一个承诺解决时动态添加的,而新的承诺也可以添加新的承诺,因此,它是一个非常动态的数组.
我拥有的真实用例是这样的:
另一个难的例子:
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()!
});
Run Code Online (Sandbox Code Playgroud)
所以,现在,一个美容的例子.我们需要在调用showAllTheInformation最后一个(我们不知道哪个是最后一个)promise时调用该函数.你怎么做呢?:
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);
}
Run Code Online (Sandbox Code Playgroud)
这里有更多上下文的另一个例子:https: //jsfiddle.net/f0a1s79o/2/
Jef*_*ica 11
你可以创建一个简洁的小递归函数来包装Promise.all来处理原始promise的补充:
/**
* Returns a Promise that resolves to an array of inputs, like Promise.all.
*
* If additional unresolved promises are added to the passed-in iterable or
* array, the returned Promise will additionally wait for those, as long as
* they are added before the final promise in the iterable can resolve.
*/
function iterablePromise(iterable) {
return Promise.all(iterable).then(function(resolvedIterable) {
if (iterable.length != resolvedIterable.length) {
// The list of promises or values changed. Return a new Promise.
// The original promise won't resolve until the new one does.
return iterablePromise(iterable);
}
// The list of promises or values stayed the same.
// Return results immediately.
return resolvedIterable;
});
}
/* Test harness below */
function timeoutPromise(string, timeoutMs) {
console.log("Promise created: " + string + " - " + timeoutMs + "ms");
return new Promise(function(resolve, reject) {
window.setTimeout(function() {
console.log("Promise resolved: " + string + " - " + timeoutMs + "ms");
resolve();
}, timeoutMs);
});
}
var list = [timeoutPromise('original', 1000)];
timeoutPromise('list adder', 200).then(function() {
list.push(timeoutPromise('newly created promise', 2000));
});
iterablePromise(list).then(function() { console.log("All done!"); });Run Code Online (Sandbox Code Playgroud)
请记住,这仅涵盖除,而且它仍然是一个有点危险:你需要确保回调整理是这样的,在飞行中任何承诺将自己添加到列表中之前的Promises.all可调用回调.
没有出路。在调用之前,您必须将所有承诺放入数组中Promise.all。在您提供的示例中,这就像将最后一行移到顶部一样简单。
如果您异步填充数组,您应该获得该数组的承诺,并使用.then(Promise.all.bind(Promise)). 如果您不知道何时停止添加承诺,那么无论如何这是不可能的,因为它们可能永远不会全部得到解决。
关于您的“美丽示例”,您将想要了解链接的魔力。正如我之前在评论中所说,您必须return对每个执行异步操作的函数做出承诺。事实上,只需添加缺少的returns:
function userClikOnLogIn() {
return $http.get('/login/user/password').then(function(data){
// ^^^^^^
if (data.logguedOk) {
return $http.get('/checkIfIsAdmin').then(function(data){
// ^^^^^^
if (data.yesHeIsAnAdmin) {
return $http.get('/getTheNameOfTheUser').then(function(data){
// ^^^^^^
if(data.userHasName) {
return $http.get('/getCurrentDate').then(function(data){
// ^^^^^^
currentDate = data.theNewCurrentDate;
});
}
});
}
});
}
});
}
userClikOnLogIn().then(function showAllTheInformation() {
// ^^^^^ now you can chain onto it!
alert('Hi ' + name + ' today is:' + date);
});
Run Code Online (Sandbox Code Playgroud)
这里没有动态增长的承诺数组,只是每个函数都为其所做的事情的(异步)结果返回一个承诺。
| 归档时间: |
|
| 查看次数: |
3708 次 |
| 最近记录: |