我试图准确了解JavaScript中的异步如何工作。
在下面的示例中,我在另一个异步数据库调用的回调中进行嵌套数据库查找(在示例中我只是使用setTimeout
)
我试图跟踪我完成所有产品(包括嵌套数据库调用)的时间的方法是递增一个名为index
的变量并检查{{1} }。
这个数据库库不支持开箱即用的Promise,所以我真的不确定还能做什么。这似乎不是正确的做法。
index == fake_data.length
我觉得我错过了一些非常基本的东西......
答案 0 :(得分:1)
您可以将回调样式代码转换为基于承诺。看看http://bluebirdjs.com/docs/api/promise.promisify.html
或者您可以使用此代码段https://gist.github.com/joelnet/ece690e942223954b1b7997ba3b1cb00#file-promisify-js
function promisify(func) {
return (...args) =>
new Promise((resolve, reject) => {
const callback = (err, data) => err ? reject(err) : resolve(data)
func.apply(this, [...args, callback])
})
}
答案 1 :(得分:1)
我不确定你的问题是什么,但看起来好像你正在尝试使用setTimeout
来模拟数据库调用,并希望只是玩承诺。如果这是正确的,我建议创建单独的函数作为您的数据库层,以便它们可以与真实的东西交换。如果你想使用setTimeout
,那么也将它包装在一个承诺中。类似的东西:
const fake_data = [{ type: 4 }, { type: 4 }, { type: 1 }, { type: 1 }, { type: 4 }, { type: 3 }, { type: 2 }];
// this just wraps setTimeout in a promise
const simulateWork = (time, func) => {
return new Promise(resolve => {
setTimeout(() => resolve(func()), time)
})
}
const getProducts = () => simulateWork(1200, () => fake_data)
const handleProduct = product => simulateWork(400, () => {
// do something with a product after some time
})
// the you can call things like
getProducts.then(products => {
products.forEach(handleProduct)
})
更新
所以,看起来你想要做一堆异步事情,然后一旦完成就做一些事情。一个很好的候选者是Promise.all()
,你传递一系列异步承诺工作,直到所有任务都解决后才能完成。
使用上面的帮助函数,您可以执行以下操作:
// function to get unique objects
const getUnique = (arr, getVal) => {
var hash = {}
var output = []
arr.forEach(item => {
if(!hash[getVal(item)]){
hash[getVal(item)] = true
output.push(item)
}
}
return output
}
getProducts.then(products => {
// get a list of unique products and map to new work
Promise.all(getUnique(products, p => p.type).map(product => handleProduct))
// this will be called once all data completed
.then(() => test2())
}