将已解决的承诺数组映射到值数组

jch*_*241 4 javascript es6-promise

我有一系列已解决的承诺:

[Promise, Promise, Promise, ...]
Run Code Online (Sandbox Code Playgroud)

这些承诺中的每一个在解决时都会返回一个值。如何创建一个函数,将这个承诺数组的映射返回到每个承诺解析到的值?

[value_1, value_2, value_3, ...]
Run Code Online (Sandbox Code Playgroud)

这是我迄今为止最接近的:

const mapPromisesToValues = promises => {
    Promise.all(promises, values => {
        // how do I return these values from mapPromisesToValues
        return values
    });
}
Run Code Online (Sandbox Code Playgroud)

更具体地说,我问的原因是因为我有一组 Promise 数组。

const collection_1 = [Promise, Promise, Promise, ...];
const collection_2 = [Promise, Promise, Promise, ...];
//...
Run Code Online (Sandbox Code Playgroud)

并且我想将映射到一组值的这些承诺集合批处理到 1 个对象中,然后我将传递给另一个将被调用一次的函数 - 在这种情况下是 React 的setState

this.setState({
    ...this.state,
    values_1,
    values_2,
    //...
});
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 6

我有一个已解决的 Promise 数组……我如何从 mapPromisesToValues 返回这些值

即使您知道承诺已解决,您也无法从您的函数中返回其值的映射。获得promise值的唯一方法是通过then回调,并且保证回调被异步调用,这意味着你的函数不能返回值;它只能返回值的承诺(例如,正如Promise.all)。

你只需要让你的函数返回Promise.all并且让函数的使用者使用它。


重新编辑:

更具体地说,我问的原因是因为我有一组 Promise 数组。

const collection_1 = [Promise, Promise, Promise, ...];
const collection_2 = [Promise, Promise, Promise, ...];
Run Code Online (Sandbox Code Playgroud)

//...

并且我想将映射到一组值的这些承诺集合批处理到 1 个对象中,然后我将传递给另一个将被调用一次的函数 - 在这种情况下是 React 的setState

this.setState({
    ...this.state,
    values_1,
    values_2,
    //...
});
Run Code Online (Sandbox Code Playgroud)

没关系,您不需要同步执行此操作。简单地:

Promise.all([
    Promise.all(collection_1),
    Promise.all(collection_2),
    // etc.
])
.then(([values_1, values_2, /*etc*/]) => {
    this.setState({values_1, values_2,/*etc*/});
});
Run Code Online (Sandbox Code Playgroud)

请注意,我在...this.state那里离开了。两个原因:

  1. 如果您根据现有状态设置状态,则必须使用 的回调版本setState,而不是接受对象的版本;和

  2. 状态更新可以是部分的,因此...this.state是不必要的额外工作。


根据您的编码环境,您可能会发现采用async/很有用await(例如,如果您正在转译,或者您正在 Node.js 上执行此操作,则可以使用 Node.js 的最新副本)。async/await允许您根据其逻辑流程而不是其同步流程编写代码。在一个async函数中,你await用来挂起该函数并等待一个 promise 来解决。async函数是返回承诺的函数的语法糖,await也是消费承诺(例如,thencatch)的语法糖。

要从同步流过渡到逻辑流,您可以将入口点设置为async处理以下错误的函数:

(async () => {
    // Your logical flow code here
}).catch(error => {
    // Handle the error
});
Run Code Online (Sandbox Code Playgroud)

然后,您的函数可能是一个async函数:

async function example() {
    // ...
    return await Promise.all(thePromises)
}
Run Code Online (Sandbox Code Playgroud)

...任何其他async功能都可以通过await以下方式使用:

let values = await example();
Run Code Online (Sandbox Code Playgroud)