承诺一定会兑现吗?

Are promises guaranteed to be executed?

假设我们有一个名为 logData 的简单函数来处理 HTTP 请求。还假设我们有另一个名为 logIntoDatabase.

的函数
async logIntoDatabase(message) { ... }

async logData(request, response) {
    await logIntoDatabase("something happened");
    response("log successful");
}

假设我们不需要确定数据是否已登录到数据库(我们不需要等待数据库的响应)。所以我们做一点优化:

async logIntoDatabase(message) { ... }

async logData(request, response) {
    logIntoDatabase("something happened");
    response("log successful");
}

绝对保证 logIntoDatabase 会执行吗? (好像我们等待它完成)

是的,只要调用它的函数(logData)也被执行,logIntoDatabase肯定会执行。

请注意,它不一定会按照您的预期执行:它可能会抛出错误或需要很长时间才能完全执行,尽管这是与函数内容相关的问题,而不是如果您将其命名为 synchronouslyasynchronously.

Script inside promise or asynchronous will always be executed unless your application/server force stop or crash.

您可以阅读这篇关于异步如何工作的文章。脚本仍在堆栈中但未阻塞其他进程。

https://blog.bitsrc.io/understanding-asynchronous-javascript-the-event-loop-74cd408419ff

是的!

JavaScript里的承诺,就像现实生活中的承诺,一旦做了,就一定会遵守。

希望对您有所帮助

Are promises guaranteed to be executed?

首先,这是术语的正确性,但 promises 不 "execute"。异步函数执行并创建可帮助您监控其完成情况的承诺。你不是在这里称呼承诺。您正在调用一个 returns 您承诺的函数。

is it ABSOLUTLY GUARANTEED that logIntoDatabase is going to execute?

是的,如果调用 logData(...),那么在您的第一个和第二个代码示例中,logIntoDatabase() 将始终作为该函数的第一行执行。

你的方法是这样的:

async logData(request, response) {
    await logIntoDatabase("something happened");
    response("log successful");
}

本质上等同于此(假设 logIntoDatabase() returns 一个承诺并且不同步抛出):

logData(request, response) {
    return logIntoDatabase("something happened").then(() => {
        response("log successful");
    });
}

因此您可以看到在 logData() 中执行的第一行是对 logIntoDatabase().

的调用

async 函数的完全替代是这样的:

logData(request, response) {
    try {
        return Promise.resolve(logIntoDatabase("something happened")).then(() => {
            response("log successful");
        });
    } catch(e) {
        return Promise.reject(e);
    }
}

这涵盖了其他不当行为,例如 logIntoDatabase() 不返回承诺或同步抛出。但是,即使在这个更完整的类比中,您也可以看到 logIntoDatabase() 仍然保证会被调用。


在您的第二个代码示例中:

async logData(request, response) {
    logIntoDatabase("something happened");
    response("log successful");
}

你仍然保证 logIntoDatabase() 会被调用。但是,这将在三个方面与使用 await 的版本在行为上有所不同:

  1. response("log successful") 将始终被调用,即使 logIntoDatabase() 拒绝。

  2. response("log successful") 将在 logIntoDabase() 完成其异步操作之前被调用。

  3. logData() 返回的承诺与 logIntoDatabase() 是否解决或拒绝没有任何关系。如果 logIntoDatabase()resolve("log successful") 都没有同步抛出,则承诺将使用 undefined 解析值解析。如果其中任何一个确实同步抛出,那么从 logData() 返回的承诺将被拒绝,并将异常作为拒绝的原因。

因此,您的第二个示例与此类似:

logData(request, response) {
    try {
        logIntoDatabase("something happened");
        response("log successful");
        return Promise.resolve();
    } catch(e) {
        return Promise.reject(e);
    }
}

而且,你可以看到 logIntoDatabase() 仍然保证总是被调用。