如何与forEach同时执行promise?

问题描述

我有一个代码可以在我的系统中更新或创建新用户。它与 forEach 函数一起使用,并且运行良好。 但是,我想利用 Node.js 并同时执行多个更新/创建。 我试图创建一系列承诺,但我认为我构建的承诺是错误的。 这是工作正常的代码

library(libr)

# Create vector lookup
species_vector <- c("setosa" = "setosa_sub","versicolor" = "versicolor_sub","virginica" = "virginica_sub")


# Step through data row by row,and assign value using lookup
df_long2 <- df_long %>%
  datastep({
  
    sub_q <- data[n.,species_vector[Species]]
  
  })

现在,我想把“更新”变成承诺,这样我就可以使用 promise.all() 同时发送几个。这是我试过的:

import usersjson from './jsons/users.json';
if (usersjson.users.length) {
    for (const user of usersjson.users) {
        let getuser = getUser(url,user.Id,'Id');
            getuser.then((data) => {//Make a call to get user by id
                if (data.users.length != 0) { //If user exists
                    let update = updateUser(url,user,data.users[0].id);//update user function
                    update.then((updateresponse) => {
                        console.log(updateresponse);
                        }).catch((err) => {
                            console.log(err);
                        })
                } else { //if user doesn't exist
                    let update = newUser(url,user);//createuser(settings.fieldMap,user)
                    update.then((response) => {
                        console.log(response);
                    }).catch((err) => {
                        console.log(err);
                    });
                }
            }) 
    };
};

但我收到一条错误消息:

(node:22016) UnhandledPromiseRejectionWarning: ReferenceError: promise 没有定义 在 file:///C:/xampp/htdocs/NodeAPI/server.js:70:21 在 processticksAndRejections (internal/process/task_queues.js:97:5) (node:22016) UnhandledPromiseRejectionWarning:未处理的承诺拒绝。这 错误源于抛出异步函数内部 没有 catch 块,或者通过拒绝未处理的承诺 用 .catch()。在未处理的承诺上终止节点进程 拒绝,请使用 CLI 标志 import usersjson from './jsons/users.json'; let promises = []; if (usersjson.users.length) { for (const user of usersjson.users) { if (promises.length <= 20) { let getuser = getUser(url,'Id'); getuser.then((data) => {//Make a call to get user by id if (data.users.length != 0) { //If user exists let update = new promise ((resolve,reject) => { updateUser(url,data.users[0].id).then((response) => { resolve(response); }).catch((err) => { console.log(err) }); }); promises.push(update); } else { //if user doesn't exist let update = new promise ((resolve,reject) => { newUser(url,user).then((response) => { resolve(response); }).catch((err) => { console.log(err); }) }); psomises.push(update); } }); } else { await promises.all(update) .then ((result) => { console.log(result); promises = []; }).catch(err){ console.log(err); } }; }; }; (请参阅 https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode)。 (rejection id: 1) (node:22016) [DEP0018] DeprecationWarning: Unhandled 不推荐使用承诺拒绝。在未来,承诺拒绝 未处理的将终止 Node.js 进程 非零退出代码

我的问题是,如何让数组中的那 20 个用户同时运行 forEach,而不是一个一个

解决方法

  1. 首先,将处理每个单独的 user 值的代码流移动到它自己单独的 async 函数中。

    • 由于 async 函数的实际工作方式(因为每个 async function 标记了每个异步状态机的边界),因此在 {{1} 中执行并发异步工作实际上并不可行} 声明。
  2. for 循环内调用该函数。

  3. 总是喜欢 for 而不是 ===

  4. 使用打字稿。在没有 TypeScript 的情况下使用 == JavaScript 是一个痛苦的世界,因为您需要跟踪哪些函数返回 async 与那些不返回,以及正确解包 Promise<T> 对象。

  5. 只要有可能,总是有自己的 Promise<T> 语句来包装 try/catch 函数的整个主体,否则你将不得不处理不同 JS 引擎和 JS 之间的不一致代码处理抛出的异常和对象。

async
,

实现这一点的最简单方法是在 foearch 方法中,将所有 Promise 引入一个数组中,然后调用它们,然后使用 Promise.all 等待一切完成。

let promiseArray = []
array.forEach(x => {
      // Do whatever you need
     promiseArray.push(updateUser(...))
     // Push only the promise without the 'then'
     // You are going to handle the response or 
     // the errors later  

})
const promiseResponses = await Promise.all(promiseArry)
// promiseResponses is an array of responses
// like promiseResponse[0]