【问题标题】:Issue with useMutation with await and promise带有等待和承诺的 useMutation 问题
【发布时间】:2021-02-25 13:59:10
【问题描述】:

我正在最内层循环中执行 useMutation 操作,并希望检查每个突变的剩余成本。但是它会在所有突变后进行检查,这是一个问题,因为出于某种原因,即使所有突变都完成(当成本低于限制时),它也会调用 .then() 部分进行成本检查并等待未知原因。

编辑:我也注意到,即使程序一次又一次地等待,chrome的网络状态显示所有的突变都发生了,只有handleDiscountMore的查询,即fetchMore是未决的

const { loading, error, data, fetchMore, extensions, refetch } = useQuery(GET_COLLECTION, {
    variables: { "id": coll.collection.id }
  });

const [updatePrice] = useMutation(UPDATE_PRICE);

const redirectToModify = async (data, totalProducts) => {
    wait(20000);
    var cursor, fetchCount;
    fetchCount = data.collection.products.edges.length;
    totalProducts -= fetchCount;

    data.collection.products.edges.map(async(product) => {
      const results = await Promise.all(product.node.variants.edges.map(variant => {
        if (selected == 'curr_price') {
          //do stuff
        }
        else {
          //do stuff
        }
        const productVariableInput = {
          //Object
        };

        updatePrice({ variables: { input: productVariableInput } }).then(({ data, extensions }) => {
          console.log("Remaining", extensions.cost.throttleStatus.currentlyAvailable) 
          console.log(data)
          if (extensions.cost.throttleStatus.currentlyAvailable < 100) {
            console.log("WAITING")
            wait(18000);
          }
        }).catch(e => {
          console.log(e)
        })
        console.log("AFTER")
        return 0;
      }))
    })
        
    if (totalProducts > 0) {
      console.log("Calling")
      wait(15000);
      handleDiscountMore(data, cursor, totalProducts)  
    }
  };

//Below function is Just for reference. It gets called before checking the throttleStatus above. afaik there's no problem with this

const handleDiscountMore = (data, cursor, pc) => { 
    console.log("Call received")
    fetchMore({
      variables: {
        "id": data.collection.id,
        "cursor": cursor
      },
      updateQuery: (
        previousResult,
        { fetchMoreResult }
      ) => {
        console.log("adding", fetchMoreResult);
        redirectToModify(fetchMoreResult, pc);
        // return fetchMoreResult;
      }
    })
  }

【问题讨论】:

    标签: node.js react-apollo apollo-client apollo-server shopify-app


    【解决方案1】:

    您的地图地图正在同时评估所有承诺。这是一个使用嵌套 for 循环的清理示例,它将等待每个请求完成后再开始下一个请求(注意:我无法运行它来测试,所以可能存在一些错误,但想法就在那里):

    const id = coll.collection.id;
    const { loading, error, data, fetchMore, extensions, refetch } = useQuery(GET_COLLECTION, {
        variables: { id }
    });
    
    const [updatePrice] = useMutation(UPDATE_PRICE);
    
    // Given a product, returns a promise that resolves when all variants are processed
    async function process_product(product){
        const variants = product.node.variants.edges;
        for (let i = 0; i < variants.length; i++){
            await process_variant(variants[i]);
        }
    }
    
    // Given a variant, returns a promise after the product is processed
    async function process_variant(variant){
        if (variant) {
            console.log('doing stuff')
        }
        else {
            console.log('doing other stuff')
        }
        const productVariableInput = {};
        const variables = { input: productVariableInput };
    
        try {
            const {data, extensions} = await updatePrice({ variables });
            const remaining_throttle = extensions.cost.throttleStatus.currentlyAvailable;
            console.log("Remaining", remaining_throttle)
            console.log(data)
    
            // Change to a while loop to make sure you actually wait until resources are available
            if (remaining_throttle < 100) {
                console.log("WAITING")
                await wait(18000);
            }
        } catch (e) {
            console.log('error:', e);
        }
        console.log("AFTER")
        return 0;
    }
    
    const redirectToModify = async (data, totalProducts) => {
        await wait(20000);
        let cursor;
        const products = data.collection.product.edges;
    
        totalProducts = totalProducts - products.length;
    
        // Wait for all products to finish processing
        for (var i = 0; i < products.length; i++){
            await process_product(products[i]);
        }
    
        if (totalProducts > 0) {
            console.log("Calling")
            await wait(15000);
            handleDiscountMore(data, cursor, totalProducts)
        }
    };
    
    function updateQuery(previousResult, { fetchMoreResult }){
        console.log("adding", fetchMoreResult);
        redirectToModify(fetchMoreResult, pc);
        return fetchMoreResult;
    }
    //Below function is Just for reference. It gets called before checking the throttleStatus above. afaik there's no problem with this
    function handleDiscountMore(data, cursor, pc) {
        console.log("Call received")
        const variables = { id: data.collection.id, cursor };
        fetchMore({ variables, updateQuery })
    }
    

    【讨论】:

      猜你喜欢
      • 2021-10-07
      • 2019-06-20
      • 1970-01-01
      • 2021-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-16
      • 2021-07-02
      相关资源
      最近更新 更多