问题描述
我有一个代码可以在我的系统中更新或创建新用户。它与 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,而不是一个一个?
解决方法
-
首先,将处理每个单独的
user
值的代码流移动到它自己单独的async
函数中。- 由于
async
函数的实际工作方式(因为每个async function
标记了每个异步状态机的边界),因此在 {{1} 中执行并发异步工作实际上并不可行} 声明。
- 由于
-
从
for
循环内调用该函数。 -
总是喜欢
for
而不是===
。 使用打字稿。在没有 TypeScript 的情况下使用
==
JavaScript 是一个痛苦的世界,因为您需要跟踪哪些函数返回async
与那些不返回,以及正确解包Promise<T>
对象。-
只要有可能,总是有自己的
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]