我怎么知道哪个诺言会首先解决?

时间:2019-10-07 17:12:25

标签: javascript promise

我有一段代码正在播放,我故意将Promise.resolve(c)放在Promise.resolve(a)之前的位置,但是我注意到true从底部Promise.all(...)开始的值首先被记录。

const https = require('https');

function getData(substr) {
    let url = ``;
    return new Promise((resolve, reject) => {
        try {
            https.get(url, res => {
                let s = '';
                res.on('data', (d) => {
                    s += d
                });

                res.on('end', () => {
                    let data = JSON.parse(s);
                    resolve(data);
                })
            })
        } catch (e) {
            reject(e);
        }
    })
}

let a = getData('spiderman');

let b;

let c = getData('superman');

Promise.resolve(c)
    .then(value => console.log(value));

Promise.resolve(a)
    .then(value => b = value);

Promise.all([a]).then(values => console.log(values[0] === b)); 

为什么会出现这种情况?我认为既然Promise.resolve(c)首先出现,所以Promise c将首先解析并记录下来。还是除了使用回调之外,没有其他方法可以真正依靠日志的顺序吗?避免此类问题的最佳做法是什么?

4 个答案:

答案 0 :(得分:4)

这些是异步调用,可以使用传递给then的提供的函数完全解析。

没有办法强制其中之一完成操作,如果需要,您应该同步运行它们。

调用.then()时,仅在函数完成时调用,而不是在.resolve被调用时。

答案 1 :(得分:2)

不能保证承诺解决顺序。这就是异步代码的重点。

如果您依赖执行顺序,则应该使用同步代码。

答案 2 :(得分:0)

如果您希望两个请求都都完成,然后再执行下一步,请对两个请求都使用Promise.all()

let a = getData('spiderman');

let c = getData('superman');

Promise.all([a, c]).then(([spidyResults, superResults]) => {
    // both have sompleted
    // do stuff with each set of results

}).catch(err => console.log('Ooops, one of them failed') );

答案 3 :(得分:0)

好吧,如前所述,不能保证承诺完成的顺序,因为它是异步操作。

如果您确实需要按照一定顺序执行程序,则需要将下一个要执行的操作放在then内,或者使用asyncawait这样更干净。 / p>