猿问

我怎样才能等待循环完成?

让我首先向您展示代码的样子


 Cart.getCompleteCart((cart)=>{

    

       let products = []; *//this Array has to be filled*


       totalPrice = cart.totalPrice;


       for(let prod of cart.products){


                Product.getProductDetails(prod.productId, productDetails => {

                    products.push({

                        product: productDetails,

                        productCount: prod.productCount

                    });

                });


      }

      console.log("Products are ->", products); *//this line is running before for loop!*

 }

       

console.log() 在 for 循环完成其工作之前运行。


如何运行与 console.log() 同步的“for 循环”?


牛魔王的故事
浏览 74回答 2
2回答

四季花海

我假设这Product.getProductDetails()是一个异步方法(它看起来像是对 API 的查询)。console.log()不是“在for循环之前运行”,只是执行的任务Product.getProductDetails()正在异步处理。由于该方法似乎也适用于回调,因此实现您的目标的一种方法是对每个调用进行承诺,然后通过使用方法Product.getProductDetails()将所有承诺压缩为一个承诺。Promise.all()这样的事情应该可以解决问题:Cart.getCompleteCart((cart) => {    const promises = [];    for (let prod of cart.products) {        promises.push(            new Promise((resolve) => {                Product.getProductDetails(prod.productId, (productDetails) => {                    resolve({                        product: productDetails,                        productCount: prod.productCount                    });                });            })        );    }    Promise.all(promises).then((products) => {        console.log('Products are ->', products);    });});或者:Cart.getCompleteCart((cart) => {    Promise.all(        cart.products.map((prod) => {            return new Promise((resolve) => {                Product.getProductDetails(prod.productId, (productDetails) => {                    resolve({                        product: productDetails,                        productCount: prod.productCount                    });                });            });        })    ).then((products) => {        console.log('Products are ->', products);    });});

慕尼黑5688855

Promise.all几乎是为这个确切的用例而设计的:// A dummy "Product" with a dummy "getProductDetails" implementation// so that we can have a working test examplelet Product = {&nbsp; getProductDetails: (productId, callback) => {&nbsp; &nbsp; setTimeout(() => {&nbsp; &nbsp; &nbsp; callback({ type: 'productDetails', productId });&nbsp; &nbsp; }, 100 + Math.floor(Math.random() * 200));&nbsp; }};// This is the function you're looking for:let getCompleteCart = async (cart) => {&nbsp;&nbsp;&nbsp; return Promise.all(cart.products.map(async ({ productId, productCount }) => ({&nbsp; &nbsp; product: await new Promise(resolve => Product.getProductDetails(productId, resolve)),&nbsp; &nbsp; productCount&nbsp; })));&nbsp;&nbsp;}let exampleCart = {&nbsp; products: [&nbsp; &nbsp; { productId: 982, productCount: 1 },&nbsp; &nbsp; { productId: 237, productCount: 2 },&nbsp; &nbsp; { productId: 647, productCount: 5 }&nbsp; ]};getCompleteCart(exampleCart).then(console.log);细分getCompleteCart:let getCompleteCart = async (cart) => {&nbsp;&nbsp;&nbsp; return Promise.all(cart.products.map(async ({ productId, productCount }) => ({&nbsp; &nbsp; product: await new Promise(resolve => Product.getProductDetails(productId, resolve)),&nbsp; &nbsp; productCount&nbsp; })));&nbsp;&nbsp;}Promise.all( mdn ) 是专门为等待承诺数组中的每一个承诺而构建的我们需要提供一个 Promise 数组给Promise.all. 这意味着我们需要将数据数组 ( cart.products) 转换为 Promises 数组;Array.protoype.map是这方面的完美工具。提供的函数cart.products.map将购物车中的每个产品转换为看起来像的对象{ product: <product details>, productCount: <###> }。这里棘手的事情是获取“product”属性的值,因为这个值是异步的(由回调返回)。Product.getProductDetails以下行使用 Promise 构造函数 ( mdn )创建一个解析为由 返回的值的promise :new Promise(resolve => Product.getProductDetails(productId, resolve))await关键字允许我们将此承诺转换为它产生的未来值。我们可以将此未来值分配给“product”属性,而“productCount”属性只是从购物车中的原始商品复制而来:{&nbsp; product: await new Promise(resolve => Product.getProductDetails(productId, resolve)),&nbsp; productCount}为了console.log在正确的时间运行,我们需要等待所有产品详细信息完成编译。幸运的是,这是由getCompleteCart. 我们可以console.log在适当的时候通过等待getCompleteCart来解决。有两种方法可以做到这一点:使用Promise.prototype.then(mdn):getCompleteCart(exampleCart).then(console.log);或者,如果我们在async上下文中,我们可以使用await:let results = await getCompleteCart(exampleCart);console.log(results);
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答