gpt4 book ai didi

javascript - 避免在 javascript 中循环多次返回 - async/await 以解决回调金字塔或回调 hell ,

转载 作者:行者123 更新时间:2023-11-30 07:53:48 26 4
gpt4 key购买 nike

我有这段代码,有很多返回 block ,例如 SignUp()

连接器.js

  const connectors = {
Auth: {
signUp(args) {
return new Promise((resolve, reject) => {
// Validate the data
if (!args.email) {
return reject({
code: 'email.empty',
message: 'Email is empty.'
});
} else if (!isEmail(args.email)) {
return reject({
code: 'email.invalid',
message: 'You have to provide a valid email.'
});
}

if (!args.password) {
return reject({
code: 'password.empty',
message: 'You have to provide a password.'
});
}

return encryptPassword(args.password, (err, hash) => {
if (err) {
return reject(new Error('The password could not be hashed.'));
}

return User.create(Object.assign(args, { password: hash }))
.then((user) => {
resolve(createToken({ id: user._id, email: user.email }));
})
.catch((err2) => {
if (err2.code === 11000) {
return reject({
code: 'user.exists',
message: 'There is already a user with this email.'
});
}

return reject(err2);
});
});
});
},
};

module.exports = connectors;

然后调用此代码的另一个代码:

 const connectors = require('./connectors');

CallsignUp(root, args) {
const errors = [];

return connectors.Auth.signUp(args)
.then(token => ({
token,
errors
}))
.catch((err) => {
if (err.code && err.message) {
errors.push({
key: err.code,
value: err.message
});
return { token: null, errors };
}

throw new Error(err);
});
}

如何在 ES6 或 ES7 或 ES2017 中避免这种情况?

有:

  return()
.then()
return()
.then

然后循环返回:

return()
return()
return()

来自 PHP 的这段代码看起来很疯狂,因为返回函数返回函数,我不清楚,javascript 中的名称如何是这种类型的 block 返回代码?调用再次返回更多代码的函数?

更新:

代码不是我的,完整源在

https://github.com/jferrettiboke/react-auth-app-example

我想通过例子来理解:

    return encryptPassword(args.password, (err, hash) => {
if (err) {
return reject(new Error('The password could not be hashed.'));
}

return User.create(Object.assign(args, { password: hash }))
.then((user) => {
.catch((err2) => {

return reject(err2);

/src/utils/auth.js(这里是encryptPassword)

const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt-nodejs');
const config = require('../config');
exports.encryptPassword = (password, callback) => {
// Generate a salt then run callback
bcrypt.genSalt(10, (err, salt) => {
if (err) { return callback(err); }

// Hash (encrypt) our password using the salt
return bcrypt.hash(password, salt, null, (err2, hash) => {
if (err2) { return callback(err2); }
return callback(null, hash);
});
});
};

返回调用函数和返回值与函数有3种? OOP 从来不是这样的,@dashmud 建议如何使用 Async/Await,我不想学习回调之类的老东西

最佳答案

此代码需要以多种方式进行重构。首先,您真的、真的不想在同一个逻辑流中混合使用 promises 和普通的异步回调。它弄得一团糟,破坏了 promise 的许多优点。然后,您有一个在 new Promise() 中使用 promises 的反模式。然后,您需要更多嵌套(您可以改为链接)。

这是我的建议:

function encryptPasswordPromise(pwd) {
return new Promise((resolve, reject) => {
encryptPassword(pwd, (err, hash) => {
err ? reject(new Error("The password could not be hashed.")) : resolve(hash);
});
});
}

const connectors = {
Auth: {
signUp(args) {
// Validate the data
let err;
if (!args.email) {
err = {code: 'email.empty', message: 'Email is empty.'};
} else if (!isEmail(args.email)) {
err = {code: 'email.invalid', message: 'You have to provide a valid email.'};
} else if (!args.password) {
err = {code: 'password.empty', message: 'You have to provide a password.'};
}
if (err) {
return Promise.reject(err);
} else {
return encryptPasswordPromise(args.password).then(hash => {
args.password = hash;
return User.create(args);
}).then((user) => {
return createToken({id: user._id, email: user.email});
}).catch(err2 => {
if (err2.code === 11000) {
throw new Error({code: 'user.exists', message: 'There is already a user with this email.'});
} else {
throw err2;
}
});
}
}
}
};

变更摘要:

  1. 最初收集所有错误,并在一个地方为所有这些初始错误返回 Promise.reject(err)
  2. Promisify encryptPassword() 这样您就不会将常规回调与 promise 逻辑流混合在一起,然后您可以正确地返回和传播错误。
  3. 使用 return new Promise() 移除整个代码的包装,因为您所有的异步操作现在都已 promise ,因此您可以直接返回 promise 。这也确实有助于正确处理错误。
  4. 取消不必要的嵌套,只用链代替。
  5. 删除 Object.assign(),因为似乎没有原因。

在您的编辑中,您要求解释此代码段:

return encryptPassword(args.password, (err, hash) => {
if (err) {
return reject(new Error('The password could not be hashed.'));
}

return User.create(Object.assign(args, { password: hash }))
.then((user) => {
.catch((err2) => {

return reject(err2);
  1. 此代码调用 encryptPassword()
  2. 它返回的结果可能是 undefined 所以 return 所做的就是控制程序流(退出包含的函数),但是因为没有代码在返回相同级别后,这是不必要的。
  3. 您将回调传递给 encryptPassword()。该回调是异步的,这意味着它会在一段时间后调用。
  4. 回调有两个参数:errhash。在 node.js 异步调用约定中,如果第一个参数是真值(例如包含一些真值),那么它表示一个错误。如果为假(通常为 null),则没有错误,第二个参数包含异步操作的结果。
  5. 如果出现错误,父 promise 将被拒绝并退出回调。同样,reject 没有返回值,因此 return 仅用于在该点退出回调(因此回调中没有其他代码运行)。
  6. 然后,调用另一个异步操作 User.create() 并将其传递给其中设置了新密码的 args 对象。
  7. User.create() 返回一个 promise,因此它的结果被 .then() 方法捕获并传递给它的回调。
  8. 一段时间后,当异步 User.create() 完成时,它将解决其 promise ,这将导致调用 .then() 回调并结果将传递给它。如果该操作出错,则不会调用 .then() 回调,而是调用 .catch() 回调。在那个 .catch() 回调中,父 promise 被拒绝。这是一个 promise 反模式(在另一个 promise 中解决父 promise),因为在正确的错误处理中很容易出错。我的回答说明了如何避免这种情况。

关于javascript - 避免在 javascript 中循环多次返回 - async/await 以解决回调金字塔或回调 hell ,,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46167078/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com