我想将产品插入数组,然后继续使用该数组。我没有使用Promisses的经验。贝娄是我的代码。 这是我想返回数组的函数。
const findProduct = async function(request) {
const products = [];
await Promise.all(
request.products.forEach(async product => {
await db
.get()
.collection('products')
.findOne({ _id: product.productId.toString() }, (err, result) => {
if (err) throw new Error('exception!');
products.push(result);
});
})
)
.then(() => {
return products;
})
.catch(e => e);
};
产品始终是不确定的。
我应该返回Promise。所有我都将其保存到一个数组中,然后使用该数组吗?
这就是我打算使用数组的方式
const purchase = new Purchase(req.body);
const products = await findProduct(req.body);
purchase.products = [...products];
答案 0 :(得分:2)
在findProduct
函数的上下文中,如果打算等待使用async
的结果,则使用await
/ findProduct
语法没有多大意义const products = await findProduct(req.body);
相反,您只想使用Promises来定义函数。
首先,db.collection.findOne()
使用异步事件的回调,要在Promise链中使用此回调,必须将其包装在Promise中。可以这样做:
new Promise((resolve, reject) => {
db
.get()
.collection('products')
.findOne({ _id: product.productId.toString() }, (err, result) => { err ? reject(err) : resolve(result) })
});
(err, result) => { err ? reject(err) : resolve(result) }
只是
(err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
}
接下来,您必须将数组传递给Promise.all()
。因为您已经有了数组request.products
,所以您可以将每个值转换(或映射)为其对应的Promise以获取其数据。这是使用Array.prototype.map
完成的。以这种方式使用时,Promise.all()
将以与request.products
相同的顺序解析为一系列产品数据对象。
将其混合到您的代码中,将产生:
const findProduct = function(request) {
return Promise.all(
request.products.map(product => {
return new Promise((resolve, reject) => {
db
.get()
.collection('products')
.findOne({ _id: product.productId.toString() }, (err, result) => err ? reject(err) : resolve(result))
});
})
);
};
请注意,我删除了.then(()=>products)
(因为Promise.all会根据上述承诺返回产品本身)和.catch(e=>e)
(因为您不应忽略这样的错误)。
有了这些更改,您现在可以像在问题中一样使用findProduct
。
更新:
似乎MongoDB API符合Promises,这意味着我们可以删除Promise回调包装并将其简化为:
const findProduct = function(request) {
return Promise.all(
request.products.map(product => {
return db
.get()
.collection('products')
.findOne({ _id: product.productId.toString() });
})
);
};
答案 1 :(得分:0)
Promise.all()
期望一个Promises数组,而map将返回一个数组。由于db
也将返回一个Promise,因此我们只将这些承诺提供给Promise.all()
编辑:忘记返回Promise.all()
并返回一个保证,因此可以与await findproducts()
或findproducts().then()
一起使用
const findProduct = function (request) {
return Promise.all(
request.products.map(product => {
return db
.get()
.collection('products')
.findOne({ _id: product.productId.toString() }
});
})
)};
由于很多人问:“我如何从Promise中得到一些东西?” ->使用解析值
这里有一个很长的解释,它为什么起作用:wait()
将返回一个Promise,该承诺将通过map()
映射到一个数组中,并返回该数组。因此,完成映射后,我们将获得一个数组,其中包含3个wait()
调用返回的3个Promises。该数组传递到Promise.all()
中,它将等待所有Promises解析,并将其自身解析为具有该数组中Promises的所有解析值的数组。由于findProduct()
将在Promise.all()
或findProduct().then()
await findProduct()
返回此承诺。
const start = { products: ['milk', 'butter', 'eggs'] }
const findProduct = function (request) {
return Promise.all(
request.products.map(product => {
return wait(product)
})
)
};
function wait(product) {
return new Promise((resolve) => {
setTimeout(() => { resolve(product) }, 5000)
})
}
findProduct(start).then(res => console.log(res))
// logs [ 'milk', 'butter', 'eggs' ]
编辑:要回答有关.then()
返回承诺的评论
findProduct(start)
.then(res => console.log(res))
.then(res => console.log(res))
// logs [ 'milk', 'butter', 'eggs' ] and undefined
findProduct(start)
.then(res => {console.log(res); return res})
.then(res => console.log(res))
// logs 2x [ 'milk', 'butter', 'eggs' ]