admin管理员组

文章数量:1432205

I have a promise implementation like the one on MDN:

    var p1 = new Promise((resolve, reject) => {
        setTimeout(resolve, 1000, "one");
    });
    var p2 = new Promise((resolve, reject) => {
        setTimeout(resolve, 2000, "two");
    });
    var p3 = new Promise((resolve, reject) => {
        setTimeout(resolve, 3000, "three");
    });
    var p4 = new Promise((resolve, reject) => {
        setTimeout(resolve, 4000, "four");
    });
    var p5 = new Promise((resolve, reject) => {
        reject("reject");
    });
    
    Promise.all([p1, p2, p3, p4, p5]).then(value => {
        console.log(value);
    }, function(reason) {
        console.log(reason)
    });

I have a promise implementation like the one on MDN:

    var p1 = new Promise((resolve, reject) => {
        setTimeout(resolve, 1000, "one");
    });
    var p2 = new Promise((resolve, reject) => {
        setTimeout(resolve, 2000, "two");
    });
    var p3 = new Promise((resolve, reject) => {
        setTimeout(resolve, 3000, "three");
    });
    var p4 = new Promise((resolve, reject) => {
        setTimeout(resolve, 4000, "four");
    });
    var p5 = new Promise((resolve, reject) => {
        reject("reject");
    });
    
    Promise.all([p1, p2, p3, p4, p5]).then(value => {
        console.log(value);
    }, function(reason) {
        console.log(reason)
    });

This does fast error-catching:

Promise.all is rejected if one of the elements is rejected and Promise.all fails fast: If you have four promises which resolve after a timeout, and one calls reject immediately, then Promise.all rejects immediately.

However, the functions inside a promise don't stop running. What I want, is that if one function does a reject, the other functions stop running (preventing useless messages to a user).

Example of a promise that keeps running after the reject:

var p1 = new Promise((resolve, reject) => {
    setTimeout(resolve, 1000, "one");
});
var p2 = new Promise((resolve, reject) => {
    setTimeout(resolve, 2000, "two");
});
var p3 = new Promise((resolve, reject) => {
    setTimeout(resolve, 3000, "three");
});
var p4 = new Promise((resolve, reject) => {
    setTimeout(() => {
        console.log('Don\'t show this after a reject!');
        resolve();
    }, 4000);
});
var p5 = new Promise((resolve, reject) => {
    reject("reject");
});

Promise.all([p1, p2, p3, p4, p5]).then(value => {
    console.log(value);
}, function(reason) {
    console.log(reason)
});

Share Improve this question asked Jul 2, 2016 at 9:36 RandyRandy 9,8495 gold badges42 silver badges58 bronze badges 2
  • 1 Keep in mind that many async operations involve networking and once they are started, some agent on some other server is already busy doing what you asked it to do. You can abort parsing the response when that es back (or kill the network connection so not response will be received), but you often cannot tell the agent on some other server to actually stop doing what it's doing. Very few networking operations have that capability. – jfriend00 Commented Jul 2, 2016 at 15:48
  • Also, another possibility is to put your processing for all the results in the Promise.all().then(...) handler. Then you will not show the user anything unless all things succeeded because you will know at that time whether there was an error or not. – jfriend00 Commented Jul 2, 2016 at 15:51
Add a ment  | 

1 Answer 1

Reset to default 4

There's nothing general in promises that will do that, since stopping the other actions is action-specific, not generic. For instance, in your example, you have to keep the timer handle and then use clearTimeout; with an ajax request, you might need to do an abort call; with something else, it would be something else.

So you'll need to handle this in your real code in a way that's specific to your real code, using .catch on the promise returned by Promise.all (or the second arg to then as you have).

In the specific code in your question, it would look something like this (I've added output to the timers we don't cancel as well), but again it will vary depending on what you're cancelling:

var timersToReject = [];
var p1 = new Promise((resolve, reject) => {
    setTimeout(v => {
        console.log("resolving " + v);
        resolve(v);
    }, 1000, "one");
});
var p2 = new Promise((resolve, reject) => {
    setTimeout(v => {
        console.log("resolving " + v);
        resolve(v);
    }, 2000, "two");
});
var p3 = new Promise((resolve, reject) => {
    setTimeout(v => {
        console.log("resolving " + v);
        resolve(v);
    }, 3000, "three");
});
var p4 = new Promise((resolve, reject) => {
    timersToReject.push(setTimeout(() => {
        console.log('Don\'t show this after a reject!');
        resolve();
    }, 4000));
});
var p5 = new Promise((resolve, reject) => {
    reject("reject");
});

Promise.all([p1, p2, p3, p4, p5]).then(value => {
    console.log(value);
}, function(reason) {
    console.log(reason)
    timersToReject.forEach(t => clearTimeout(t));
});

本文标签: javascriptbreak promiseall on catchStack Overflow