【问题标题】:How does promise all guarantee return order in es6 [duplicate]es6中如何承诺所有保证退货单[重复]
【发布时间】:2018-07-22 00:50:04
【问题描述】:

我正在使用 ES6 JavaScript 并根据返回顺序进行 API 调用。 http客户端是axios。一位同事指示我使用Promise.all()。它有效并且我知道它可以保证,但我不确定如何它可以保证结果是有序的。我的理解是不保证异步请求!我的简化代码是:

Promise.all([
    axios.get('/cars'),
    axios.get('/road-conditions')
]).then(values => {

    this.cars = values[0]
    this.roadConditions = values[1]

})

我想了解如何 values 知道哪个请求是哪个。这是 Axios 的特殊功能吗?

【问题讨论】:

  • Promise.all 以与传递给它的承诺数组相同的顺序为您提供解析值。这里不能保证请求到达服务器的顺序。
  • 感谢您的回复,我明白数组中的顺序是受尊重的,我只是不清楚promise如何保证顺序。
  • Promise.all 一直等到数组中的所有 promise 都已履行,然后才会履行。因此,无论收到的顺序如何,您都会按照指定的顺序获得答案。

标签: javascript ecmascript-6 promise axios


【解决方案1】:

这并没有什么绝妙的技巧:Promise.all 只是记住了 Promise 的索引并将该 Promise 的结果保存到它构建的数组中的正确槽中。它不只是使用push 来构建数组(因为那确实会很混乱)。

下面是一个示例,它向您非常大致展示了幕后发生的事情:

function randomDelay(val) {
    return new Promise(resolve => {
        setTimeout(
            resolve,
            Math.random() * 1000,
            val
        );
    });
}

// See: https://tc39.es/ecma262/#sec-performpromiseall
function fakeAll(iterable) {
    return new Promise((resolve, reject) => {
        const values = [];
        let remainingElementsCount = 1;
        let index = 0;
        for (const value of iterable) {
            const thisIndex = index;     // Remember the index for this result
            Promise.resolve(value)       // To handle thenables and raw values
            .then(val => {
                console.log(`values[${thisIndex}] = ${JSON.stringify(val)}`);
                values[thisIndex] = val; // <=== Notice use of `thisIndex`
                --remainingElementsCount;
                if (remainingElementsCount === 0) {
                    resolve(values);
                }
            }).catch(reject);
            ++remainingElementsCount;
            ++index;
        }
        --remainingElementsCount;
        if (remainingElementsCount === 0) {
            resolve(values);
        }
    });
}

// Pass in an iterable of promises, raw values, and thenables
fakeAll([
    randomDelay("one"),
    "two",                                      // Raw value
    randomDelay("three"),
    {then(cb) { cb("four"); }},                 // Synchronous thenable
    {then(cb) { setTimeout(cb, 20, "five"); }}, // Asynchronous thenable
])
.then(results => {
    console.log(results);
})
.catch(error => {
    console.error(error);
});
.as-console-wrapper {
  max-height: 100% !important;
}

这是 axios 的特殊功能吗?谢谢。

不,它是由 Promise.all 的规范定义的。

【讨论】:

  • 我明白了,谢谢你的解释。
猜你喜欢
  • 2019-11-09
  • 2017-03-12
  • 1970-01-01
  • 2019-01-14
  • 1970-01-01
  • 1970-01-01
  • 2017-09-25
  • 2016-06-29
  • 2017-08-19
相关资源
最近更新 更多