我正在学习承诺,我绝对希望在继续之前先了解自己的用法。我正在使用在线服务库,该库具有返回承诺的功能。
我读过的几乎所有示例都在链式setkey(dt,x)
函数中使用了已解析的数据
then()
或在const result = Library.functionReturningAPromise()
result.then(function(res) {
const obj = new Example(res)
return obj
}).then(function(ob) {
// do the rest of the logic within these then() functions
})
函数中使用已解析的数据
async
我想知道是否有任何方式可以使用“常规”同步代码中已解析的承诺中的数据
async function test() {
const result = await Library.functionReturningAPromise()
const obj = new Example(result)
// do the rest of the logic
}
或者如果您需要始终“包装” 所有,则您的逻辑将使用来自 const result = Library.functionReturningAPromise()
// do something to resolve the promise
const obj = new Example(result)
函数中已解决的承诺中的数据。
答案 0 :(得分:1)
如果您要“离开”异步上下文,则可以等待Promise完成,然后then()
调用您的“常规”函数之一作为回调。
我知道异步编码风格可能会非常混乱,但这实际上就是then(function () {})
所做的事情。
如果您更易于理解或使用此编码样式,则它在功能上是等效的。
function first() {
console.log("sync!");
doAsync();
}
function doAsync() {
console.log("now we're async!");
Library.functionReturningAPromise().then(second);
}
function second() {
console.log("sync again!");
// ...
}
答案 1 :(得分:1)
我想知道是否有任何方法可以使用“正常”同步代码中已解析的承诺中的数据
在处理异步响应时,无法编写完全同步的代码。一旦任何操作都是异步的,您就必须使用异步技术来处理响应,并且无法对其进行同步编程。您必须学习异步编程。
您显示的两个选项(.then()
或async/await
)是您处理返回的承诺的两个选择。
或者如果您需要始终“包装”使用异步函数中已解决的promise中的数据的所有逻辑。
如果您想使用await
以便编写用于处理承诺的同步外观代码,则所有这些代码都必须位于async
函数内部。而且,一旦您离开了该函数的范围(例如想要返回值),就从async
函数返回了一个Promise,再次必须处理该Promise。
无法解决此问题。这只是用Java语言必须学习的东西。一段时间后,它的确变成了第二天性。
您似乎已经知道,可以使用async
和await
来获得一些看起来很同步的逻辑流,但是有一些事情可以确保您理解这样做的目的。从您的示例中:
async function test() {
const result = await Library.functionReturningAPromise()
const obj = new Example(result);
// do the rest of the logic
}
async
声明的函数都返回一个Promise。那是您从他们那里获得的唯一一种返回值。如果调用方正在寻找返回值,或者想知道异步操作何时完成或正在寻找错误,则他们必须与.then()
,.catch()
或与{{1}一起使用返回的诺言}放在await
函数中。async
,并且需要在本地处理拒绝,则需要将它们包装在await
中(语法与同步异常非常相似)。以下是将try/catch
与try/catch
结合使用以本地处理错误的示例:
await
以下是呼叫者处理错误的示例:
async function test() {
try {
const result = await Library.functionReturningAPromise()
const obj = new Example(result);
// do the rest of the logic
} catch(e) {
// handle promise rejection here
}
}
答案 2 :(得分:0)
如果将的用途包装在返回默认值的函数中,则可以使用async/await
和then()
的组合来进行同步编程。
这是一个使用记忆来返回结果或在需要时查询它的示例:
const scope = {
// someResult is wrapped in an object so that it can be set even if it's a primitive
// (e.g. number / string).
someResult: null as number[] | null,
};
function getResult() {
if (scope.someResult !== null) {
// If we already have a result, return it. No need to query Library again.
return scope.someResult;
}
// Note: This example doesn't implement debouncing (avoiding repeated Library queries while
// Library is still being queried).
queryLibrary().then(result => {
if (scope.someResult === null) {
// If the Library call succeeded and we haven't already stored its result, store it.
scope.someResult = result;
console.log('We have a result now!', getResult());
}
});
return scope.someResult;
}
async function queryLibrary() {
const result = await functionReturningAPromise();
// Do some stuff with result in a nice async / await way.
result.push(9000, 1336);
return result;
}
/** This is some complicated async function from Library. */
async function functionReturningAPromise() {
return [419, 70];
}
// Calling getResult() will return either null or a list of numbers.
console.log('Do we have a result yet?', getResult());