我有一个函数,可以根据数据库的响应修改变量。
function f () {
let x = { };
redis.get ("key1").then ( value => x.prop1 = value);
redis.get ("key2").then ( value => x.prop2 = value);
return x;
}
这是我的大致代码。它实际上是在一个for循环中,使用node-redis。
我多次调用 Redis。我将 Redis 中的数据添加到一个新对象并返回该对象。
问题:函数f ()
每次我调用它时都会返回一个空对象。
如何在返回对象之前等待所有 Redis promise 解析?
最佳答案
在您的代码中,您不会在返回 x
之前等待 redis 值解析。为此,您应该将其包含在 async-await
中。
另外,请注意,调用 f()
不会直接返回值,而是返回一个 promise
。
async function f () { // note async
let x = { };
await redis.get ("key1").then ( value => x.prop1 = value); // note await
await redis.get ("key2").then ( value => x.prop2 = value);
return x;
}
然后您可以像 f().then(console.log)
示例:
//var Promise = require('bluebird')
console.log("started");
var f = async function() {
return {
prop1: await Promise.delay(3000).then(_ => 3),
prop2: await Promise.delay(2000).then(_ => 4)
}
}
f().then(console.log)
<script src="https://cdn.jsdelivr.net/bluebird/3.5.0/bluebird.js"></script>
也可以简化为:
async function f () {
let x = { };
return { prop1: await redis.get('key1'), prop2: await redis.get('key2') }
}
编辑:进一步考虑这一点,我认为您应该放弃此用例的 async-await,而使用 Promise.all
。原因 - 这两个 redis get
操作可以同时发生,不应该等待轮到它。使用 await
将停止第二个 redis 调用。尝试运行上面的示例代码片段,您会注意到结果总共需要 5 秒 (3 + 2),而很容易就需要大约 3 秒。
Promise.all
接受一堆 Promise 并等待它们全部解析,然后再调用它的解析。
console.log("started");
var f = function() {
var x = {}
var promises = [
Promise.delay(3000).then(_ => { x.prop1 = 3 }),
Promise.delay(2000).then(_ => { x.prop2 = 4 })
]
// wait for all of above to resolve and then resolve with `x`
return Promise.all(promises).then(_ => x)
}
f().then(console.log)
<script src="https://cdn.jsdelivr.net/bluebird/3.5.0/bluebird.js"></script>
^ 现在尝试运行此代码片段并记下时间差异。
关于javascript - 如何在数据库响应之前延迟函数返回值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51120612/