使用await在try / catch块中声明一个const

时间:2018-05-25 03:37:57

标签: javascript node.js

所以我现在有这个:

var item_id
try {
    item_id =
        await
            (async function () {
               // code
            })();
} catch (error) {

}

但我更喜欢将item_id作为常量。如果节点要求我处理承诺拒绝

,那么将await值分配给const的最佳方法是什么

e.g。错误:

[0] (node:77118) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: details[Symbol.iterator] is not a function
[0] (node:77118) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

异步代码

await
    (async function () {
        const query = `
            INSERT INTO item (list_id)
            SELECT 
                ?
            FROM
                list
            WHERE
                id = ?
                AND
                user_id = ?
            LIMIT 1;
        `

        const results =
            await
                doQuery({
                    inputs: [
                        list_id,
                        list_id,
                        req.session.user.id
                        // 10
                    ],
                    query,
                    error_message: "item create mysql error"
                })
        return results.insertId === 0 ? false : results.insertId
    })();

doQuery

function doQuery({ query, inputs, error_message, res = null }) {
    return (
        new Promise(function (resolve, reject) {
            db.query(query, inputs, function (err, results, fields) {
                if (err) {
                    console.trace(chalk.green(db.sql))
                    console.log()
                    handleError({ error: err, error_message, res })
                    reject(err)
                    return
                }

                resolve(results)
            })
        })
    )
}

的HandleError

function handleError({ error, message, res }) {
    console.trace(chalk.yellow(message))
    console.trace(chalk.red(error))
    console.log()

    if (res) {
        res.send({
            error: true,
            success: false,
        })
    }
}

3 个答案:

答案 0 :(得分:4)

这是一个众所周知的问题,已在别处讨论过。

您的选择包括:

  1. 正如您所做的那样,只需在外层声明item_id let。没错。

  2. 根据您对item_id的要求,在try/catch块内执行该操作,以便在const item_id;内声明try

  3. 确保您确实需要try/catch。请记住,async函数中抛出的任何错误都将自动转换为对函数返回的promise的拒绝。你不必(并且在某些情况下不想)抓住它;相反,在更高级别处理错误。 Node"要求你处理承诺拒绝"并不意味着你必须在这里发生它;你可以在任何更高级别处理它。请记住,此处出现错误的catch会将异步功能重新放回"快乐路径" (除非你重新抛出)并且调用函数无法知道是否有错误。

  4. 在某些情况下,如果您回到使用承诺,您的代码将更具可读性,.catch()就像在

    中一样
    const item_id_promise = async function () {}();
    
    item_id_promise.catch(...);
    

    或甚至可能只是

    return (async function() { }()).catch(...)
    
  5. 但实际上您的问题与awaitasync或承诺无关。它只是块内变量的块范围,在这种情况下是try块。是的,constlet是块范围的,因此范围限定为try子句。与其他任何内容一样,如果您想在try块之外使用它们,则必须在try块之外声明它们。或者,如果您真的不想在try块之外声明它们,则无法在try块之外使用它们,因此您必须安排在// this delays execution until after the page has loaded $( document ).ready(function() { // this monitors the button, id=submit-form-1, for a click event // and then runs the function, submitForm1() $('#submit-form-1').on('click', function() { submitForm('#form1'); }); // could be repeated for another form... $('#submit-form-2').on('click', function() { submitForm('#form2'); }); }); // this function does an AJAX call to "insert.php". // it expects a reply in JSON. function submitForm(whichForm) { var datastring = $(whichForm).serialize(); // see what you're sending: alert('You would be sending: ' + datastring); $.ajax({ type: "POST", url: "insert.php", data: datastring, dataType: "json", success: function(data) { if(data.status=='success') { alert('successfully uploaded'); } else { alert('failed to insert'); } }, error: function() { alert("This example can't actually connect to the PHP script, so this error appears."); } }); }块内使用它们它,如果可能的话。

答案 1 :(得分:1)

遵循@ torazaburo的建议:

const item_id = async function () {
  // code
  return 1337; // return your expected item id
}();
item_id.catch(function (e) {
  console.error(e);
});

答案 2 :(得分:1)

您可以使用Promises的强大功能在另一个范围内定义您的函数,例如:

async function foo(bar) {
    return new Promise((resolve, reject) => {
         if(bar === 'baz') {
              resolve(bar); // Resolve this promise
         } else {
              reject(); // Reject this promise
         }
    });
}

foo('baz').then(baz => {
    // Do something with 'baz', the result of the resolved promise
}).catch(error => {
    // The promise is rejected, process an error here
});