- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
总的来说,我对 Javascript 和 Node.js 还很陌生。因此,我试图了解 Node.js 中异步编程的概念以及如何在 AWS lambda 中使用它。
我在亚马逊博客上看到这篇博文,其中解释了 Node.js lambda 函数中对异步/等待的支持:https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/
据我所知,生成 promise 的函数的概念如下面的代码片段所示:
const func1 = () => {
console.log("Starting with execution of func1...")
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("First promise ended after 3 secs")
}, 3000)
})
}
所以这里的函数显式地生成一个 Promise 并返回它。
但在上面的 AWS 博客文章中,我看到了这样一个函数定义:
let AWS = require('aws-sdk');
let lambda = new AWS.Lambda();
exports.handler = async (event) => {
return await lambda.getAccountSettings().promise() ;
};
现在我已经检查了 AWS SDK for Node.js 文档 (https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda.html#getAccountSettings-property),我看到函数 getAccountSettings 接受回调作为第三个参数。
我对生成 promise 的 .promise()
语法感到困惑。一个函数如何确保使用该语法它会返回一个 promise 对象。因为从文档中没有提到如果我使用 .promise()
它会返回一个 promise 。我假设在这方面可能存在经验法则。
如果我只是写 return await lambda.getAccountSettings().promise()
而不是 return await lambda.getAccountSettings().promise()
会有什么不同呢。
有没有我可以引用的相关文档?
请您进一步说明这种取回 promise 对象的新方法。
提前感谢您的帮助。
最佳答案
如果您想了解为什么可以使用 .promise()
方法,以及为什么不直接返回 promise,请注意这样的 API 是如何随着时间的推移而演变的,并且必须保持向后兼容性。
让我们构建一些类似的东西,但要简化得多。让我们创建一个函数,它为给定数字提供 1/x,但在 x=0 时提供错误对象。这将异步完成。
此外,我们希望该函数同步返回一个对象,该对象允许一个人在发生错误时注册一个监听器,在成功时注册一个监听器,在两者中的任何一个发生时注册一个监听器.这是 AWS 返回的一个非常简化的想法:在那里你得到了一个非常丰富的 Request
对象。
假设我们在 2012 年,而 JavaScript 中的 promise 尚未广泛可用/使用。因此,我们为我们的异步 1/x 函数提供以下 API:
// Implementation in the first version of the API (without promises):
// * returns an object with which you can register a listener
// * accepts an optional callback
function getAsyncInverse(num, callback) {
var onSuccess = [], // callbacks that are called on success
onError = [], // callbacks that are called on failure
onComplete = []; // callbacks that are called in both situations
if (callback) onComplete.push(callback);
function complete(err=null) {
var result = null;
if (num === 0) err = new Error("Division by Zero");
else result = 1/num;
// Communicate the result/error to the appropriate listeners:
if (err) for (var i = 0; i < onError.length; i++) onError[i](err);
else for (var i = 0; i < onSuccess.length; i++) onSuccess[i](result);
for (var i = 0; i < onComplete.length; i++) onComplete[i](err, result);
}
var timeoutId = setTimeout(complete, 100);
var request = {
on: function (type, callback) {
if (type === "success") onSuccess.push(callback);
else if (type === "error") onError.push(callback);
else if (type === "complete") onComplete.push(callback);
return request;
},
abort: function () {
clearTimeout(timeoutId);
complete(new Error("aborted"));
return request;
}
}
return request;
}
// How version 1 is used, by registering a listener via the returned object
var num = 2;
var request = getAsyncInverse(num); // let's not pass a callback here
request.on("success", function (result) { // ... but use the request object
console.log("The result is:", result);
}).on("error", function (err) {
console.log("There was an error:", err);
});
但随后 promises 变得越来越流行,您的 API 的用户正在插入 promise API。您希望确保向后兼容性,因此决定只使用一个附加属性扩展返回的请求对象,一种方法:promise()
下面是如何改变上述实现以实现这一点:
// Implementation in the second version of the API (with promise), but backwards-compatible
// * returns an object with which you can register a listener, or get the promise object
// * accepts an optional callback
function getAsyncInverse(num, callback) {
let onSuccess = [], // callbacks that are called on success
onError = [], // callbacks that are called on failure
onComplete = []; // callbacks that are called in both situations
if (callback) onComplete.push(callback);
let request;
// New: create a promise, and put the logic inside the promise-constructor callback
let promise = new Promise(function (resolve, reject) {
function complete(err=null) {
let result = null;
if (num === 0) err = new Error("Division by Zero");
else result = 1/num;
// Communicate the result/error to the appropriate listeners:
if (err) for (let callback of onError) callback(err);
else for (let callback of onSuccess) callback(result);
for (let callback of onComplete) callback(err, result);
// New: also call resolve/reject
if (err) reject(err);
else resolve(result);
}
let timeoutId = setTimeout(complete, 100);
request = {
on: function (type, callback) {
if (type === "success") onSuccess.push(callback);
else if (type === "error") onError.push(callback);
else if (type === "complete") onComplete.push(callback);
return request;
},
abort: function () {
clearTimeout(timeoutId);
complete(new Error("aborted"));
return request;
},
promise: function () { // <--- added feature!
return promise;
}
};
});
return request; // We return the same as in version-1, but with additional promise method
}
// How version 2 is used, by getting the new promise method
let num = 2;
let promise = getAsyncInverse(num).promise();
promise.then(function (result) {
console.log("The result is:", result);
}).catch(function (err) {
console.log("There was an error:", err);
});
如您所见,省略请求对象并让函数返回 promise 并不是一个好主意。这会破坏使用您的 API 的现有代码(不向后兼容)。
关于javascript - Promise 如何在 Node.js 和 AWS lambda 函数中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58154076/
可以使用 lambda 和函数创建有序对(Lisp 中的缺点),如 Use of lambda for cons/car/cdr definition in SICP 所示。 它也适用于 Python
我正在尝试从另一个调用一个 AWS lambda 并执行 lambda 链接。这样做的理由是 AWS 不提供来自同一个 S3 存储桶的多个触发器。 我创建了一个带有 s3 触发器的 lambda。第一
根据以下源代码,常规 lambda 似乎可以与扩展 lambda 互换。 fun main(args: Array) { val numbers = listOf(1, 2, 3) f
A Tutorial Introduction to the Lambda Calculus 本文介绍乘法函数 The multiplication of two numbers x and y ca
我想弄清楚如何为下面的表达式绘制语法树。首先,这究竟是如何表现的?看样子是以1和2为参数,如果n是 0,它只会返回 m . 另外,有人可以指出解析树的开始,还是一个例子?我一直找不到一个。 最佳答案
在 C++0x 中,我想知道 lambda 函数的类型是什么。具体来说: #include type1 foo(int x){ return [x](int y)->int{return x * y
我在其中一个职位发布中看到了这个问题,它询问什么是 lambda 函数以及它与高阶函数的关系。我已经知道如何使用 lambda 函数,但不太自信地解释它,所以我做了一点谷歌搜索,发现了这个:What
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
Evaluate (((lambda(x y) (lambda (x) (* x y))) 5 6) 10) in Scheme. 我不知道实际上该怎么做! ((lambda (x y) (+ x x
我正在处理 MyCustomType 的实例集合如下: fun runAll(vararg commands: MyCustomType){ commands.forEach { it.myM
Brian 在他对问题 "Are side effects a good thing?" 的论证中的前提很有趣: computers are von-Neumann machines that are
在 Common Lisp 中,如果我希望两个函数共享状态,我将按如下方式执行 let over lambda: (let ((state 1)) (defun inc-state () (in
Evaluate (((lambda(x y) (lambda (x) (* x y))) 5 6) 10) in Scheme. 我不知道实际上该怎么做! ((lambda (x y) (+ x x
作为lambda calculus wiki说: There are several possible ways to define the natural numbers in lambda cal
我有一个数据类,我需要初始化一些 List .我需要获取 JsonArray 的值(我使用的是 Gson)。 我做了这个函数: private fun arrayToList(data: JsonAr
((lambda () )) 的方案中是否有简写 例如,代替 ((lambda () (define x 1) (display x))) 我希望能够做类似的事情 (empty-lam
我在 Java library 中有以下方法: public void setColumnComparator(final int columnIndex, final Comparator colu
我正在研究一个函数来计算国际象棋游戏中棋子的有效移动。 white-pawn-move 函数有效。当我试图将其概括为任一玩家的棋子 (pawn-move) 时,我遇到了非法函数调用。我已经在 repl
考虑这段代码(在 GCC 和 MSVC 上编译): int main() { auto foo = [](auto p){ typedef decltype(p) p_t;
我正在阅读一个在 lambda 内部使用 lambda 的片段,然后我想通过创建一个虚拟函数来测试它,该函数从文件中读取然后返回最大和最小数字。 这是我想出来的 dummy = lambda path
我是一名优秀的程序员,十分优秀!