gpt4 book ai didi

javascript - Promise 链未按预期顺序执行

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

我正在尝试使用一系列 promise 来验证用户名和密码,但 promise 过早解决。

这里涉及两个不同的文件,我有两种方法。

首先是我的 Controller ,它接收请求并调用我的模型进行身份验证。该模型应该返回一个 promise ,该 promise 将在解析时获得身份验证结果。

这是我的 Controller :

router.post('/api/auth-tokens', function (req, res, next) {
var creds = {user: req.body.user, password: req.body.password};
people.authenticate(creds)
.then(function (result) {
var status = result.valid ? 200: 401;
res.sendStatus(status);
});
});

people 是词法范围模型。这是上面使用的方法的当前实现:

var bluebird = require('bluebird');
var bcrypt = require('bcrypt');
var compare = bluebird.promisify(bcrypt.compare);

exports.authenticate = function (args) {
var promise = orm.select({
db: db,
table: table,
where: {id: args.user},
qrm: 'one'
});

promise.catch(function (err) {
var auth_info = { valid: false };
return auth_info;
});

promise.then(function (user) {
var promise = compare(args.password, user.hash)
.then(function (same) {
var auth_info = { valid: same, permissions: user.permissions };
return auth_info;
});
return promise;
});

return promise;
};

orm 返回一个 promise ,如果用户不存在将抛出错误,或者如果找到用户则解析并生成数据库行。 (这就是为什么我在那里调用 promise.catch 的原因。以防用户不存在)

如果用户确实存在,我想调用 bcrypt.compare将输入与数据库行中包含的散列进行比较。异步完成后,我想解析 promise 链并将控制权交还给 Controller ,返回 results 对象。

我遇到的问题是,我的 Controller 中的 .then 会立即执行,并会立即执行调用 orm.select 时返回的初始 promise 的结果>。谁能解释为什么会发生这种情况以及我该如何解决?

最佳答案

之所以会发生,是因为您已将该回调直接连接到 orm.select 返回的 promise 。 .相反,您需要使用 then 返回的 promise .

这是关于 promise 的最关键的事情之一: then返回一个新的 promise 。 (catch 也是如此。)如果您的处理函数从 then 返回一个 promise (从技术上讲,任何 thenable)或 catch , 新 promise then (或 catch )返回将根据您返回的 promise 解决/拒绝。如果您的处理程序函数返回非 promise 值,则来自 then 的新 promise (或 catch )使用该值解决(未拒绝)。

所以 authenticate应该看起来像这样:

exports.authenticate = function (args) {
return orm.select({
db: db,
table: table,
where: {id: args.user},
qrm: 'one'
})
.then(function (user) {
return compare(args.password, user.hash)
.then(function (same) {
var auth_info = { valid: same, permissions: user.permissions };
return auth_info;
});
})
.catch(function (err) {
var auth_info = { valid: false };
return auth_info;
});
};

请注意,这些更改既针对您的外部函数,也针对您在 then 中所做的事情。 .另请注意 catch 中的代码回调将被调用,无论它是来自 orm.select 的原始 promise 被拒绝的,或者来自 compare 的那个.

要了解发生了什么,请将此代码段与后面的代码段进行比较:

// Returning the original promise
// Usually NOT what you want
function foo() {
var promise = new Promise(function(resolve) {
console.log("Starting first promise");
setTimeout(function() {
console.log("Resolving first promise");
resolve("first");
}, 500);
});
promise.then(function() {
promise = new Promise(function(resolve) {
console.log("Starting second promise");
setTimeout(function() {
console.log("Resolving second promise");
resolve("second");
}, 500);
});
});
return promise;
}
foo().then(function(result) {
console.log("Got result: " + result);
});

第二个:

// Returning the original promise
// Usually NOT what you want
function foo() {
return new Promise(function(resolve) {
console.log("Starting first promise");
setTimeout(function() {
console.log("Resolving first promise");
resolve("first");
}, 500);
})
.then(function() {
return new Promise(function(resolve) {
console.log("Starting second promise");
setTimeout(function() {
console.log("Resolving second promise");
resolve("second");
}, 500);
});
});
}
foo().then(function(result) {
console.log("Got result: " + result);
});

关于javascript - Promise 链未按预期顺序执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38554982/

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