【问题标题】:Method does not wait for Promise to be resolved方法不等待 Promise 解决
【发布时间】:2021-05-18 09:54:44
【问题描述】:

我正在尝试调用一个函数,并且基本上强制它等待响应,然后再继续下一件事。

我有两个函数,都是异步的。

第一个看起来像这样,所有以“_”开头的参数都用作回调:

async function formatJson(input, _sendToThirdParty, _handleLogs, _setDimensions)
{
     ...do some work here to format the payload
     if(onlineConnectionRequired)
    {
         _setDimensions(itemToUpdate, object);
    }
    else {
         // Do non-online based transformations here
    }
    ...do more work after the above
}

基本上,我正在尝试调用这个方法 setDimensions,如下所示:

async function setDimensions(itemToUpdate, object) {
    try
    {
        if(itemToUpdate != null)
        {
            console.log("Loading dimensions");
    
            await Promise.resolve(function() {
                ns.get(`inventoryItem/${object['Item ID']}?expandSubResources=true`)
                .then((res) => {
                    console.log("Inventory Item Loaded. Updating dimensions...");

                    itemToUpdate.consignments.push(
                        {
                            consignmentID: object.conID,
                            barcode: object.barcode,
                            itemID: '', // leaving as empty for now
                            width : res.data.custitem_width,
                            length : res.data.custitem_length,
                            height : res.data.custitem_height,
                            weight : res.data.custitem_weight,
                            fragile: object.fragile === 'T' ? 1 : 0,
                            description: object.description
                        }
                    );

                    console.log("Dimensions Finalised");
                })
            });
        }
    }
    catch(err)
    {
        console.log(err);
        const message = `Error attempting to set the dimensions for ${object['Item ID']}`;
        console.log(message);
        throw new Error(message);
    }
}

我遇到的问题是:

  1. 第一种方法的代码在等待 Promise 解决之前继续运行,但我需要它等待,这样我才能完全构建有效负载,然后再继续执行下一个位
  2. 如果我尝试在第一种方法中调用 _setDimensions(...) 之前包含 await 关键字,则会收到错误 “SyntaxError: await is only valid in async function”,但我会认为它一个异步函数吗?

如果有人可以提供帮助,那将不胜感激!谢谢!!

【问题讨论】:

  • 使用promise构造函数而不是Promise.resolve
  • ns.get 看起来已经返回了一个承诺
  • 第一个函数中回调的_setDimensions 参数是否正在调用第二个函数?或者它只是你的回调函数的命名偏好?其次,为什么不使用单个回调并根据回调数据继续工作?
  • 函数_setDimentions是否返回一个Promise?其次,await Promise.resolve() 可能会在回调完成之前立即解决。你应该改用new Promise()
  • "我会认为它是一个异步函数?" - 是的,formatJsonasync function。请向我们展示您尝试过的确切代码,不要省略任何内容。

标签: javascript node.js asynchronous


【解决方案1】:

你的函数的正确设计如下:

formatJson(input, (err, value) => {
    if(err) {
        // Error handler goes here
        //console.log(err);
        throw err;
    } else {
        // Implementation for working with returned value
        console.log(value);
    }
});

function formatJson(input, callback)
{
    //...do some work here to format the payload
    if(onlineConnectionRequired)
    {

        setDimensions(itemToUpdate, object)
            .then((updatedItem) => {
                // Implement anything here to work with your
                // result coming from setDimensions() function

                //console.log(updatedItem);

                // Callback with null error and updatedItem as value
                callback(null, updatedItem);
            })
            .catch((err) => {
                // Callback with err object and null value
                callback(err, null);
            });
    }
    else {
         // Do non-online based transformations here
    }
    //...do more work after the above
}

function setDimensions(itemToUpdate, object) {
    try
    {
        if(inventoryItemID != null)
        {
            console.log("Loading dimensions");
    
            return new Promise(function(resolve, reject) {
                ns.get(`inventoryItem/${object['Item ID']}?expandSubResources=true`)
                    .then((res) => {
                        console.log("Inventory Item Loaded. Updating dimensions...");

                        itemToUpdate.consignments.push(
                            {
                                consignmentID: object.conID,
                                barcode: object.barcode,
                                itemID: '', // leaving as empty for now
                                width : res.data.custitem_width,
                                length : res.data.custitem_length,
                                height : res.data.custitem_height,
                                weight : res.data.custitem_weight,
                                fragile: object.fragile === 'T' ? 1 : 0,
                                description: object.description
                            }
                        );

                        console.log("Dimensions Finalised");

                        resolve(itemToUpdate);
                    })
                    .catch((err) => reject(err));
            });
        }
    }
    catch(err)
    {
        console.log(err);
        const message = `Error attempting to set the dimensions for ${object['Item ID']}`;
        console.log(message);
        throw new Error(message);
    }
}

代码中的错误:

  1. 您的formatJson 函数有async 关键字,但您的formatJson 函数有名为_sendToThirdParty, _handleLogs, _setDimensions 的回调函数。有 3 种类型的实现来创建异步代码。你可以使用回调、Promises 或 async/await。但是 Promises 和 async/await 是相同的,除了它们的用例和语法。当您将函数定义为 async fn() {...} 时,它基本上返回一个新的 Promise,因此等于说 fn() { return new Promise(); }。带有回调的函数具有类似function(params, callback) { callback(cbParams); } 的形状,您可以在函数的多个分支中使用调用回调函数。但是你只有一个回调函数,你的代码有 3 个回调函数。另请注意,带有回调的函数没有 async 关键字。这是无效的,因为正如我之前提到的,异步函数会返回一个 Promise。所以你不应该(但你可以)将函数定义为async function(params, callback),就像你在第一个方法中所做的那样。这是定义没有错,它可以工作,但它是无效的。

  2. 您的第二种方法是一个异步函数,它什么都不返回。所以我把它改成了普通函数,返回一个 Promise。

【讨论】:

    【解决方案2】:

    formatJson 方法是否在异步方法中被调用?它需要,并且在 _setDimensions 之前,您需要添加一个 await 关键字。 而且,正如 Daniel 所说,使用 promise 构造函数。

    【讨论】:

    • 在异步函数中不需要使用formatJson,您可以在同步(普通)函数中将其用作formatJson.then().catch()。在函数声明之前添加的 async 关键字的作用是让你的 async 函数返回一个 Promise。
    猜你喜欢
    • 2020-06-23
    • 1970-01-01
    • 2021-05-19
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多