同步使用已解决的承诺数据

时间:2018-07-25 12:50:52

标签: javascript asynchronous promise synchronous

我正在学习承诺,我绝对希望在继续之前先了解自己的用法。我正在使用在线服务库,该库具有返回承诺的功能。

我读过的几乎所有示例都在链式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) 函数中已解决的承诺中的数据。

3 个答案:

答案 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语言必须学习的东西。一段时间后,它的确变成了第二天性。


您似乎已经知道,可以使用asyncawait来获得一些看起来很同步的逻辑流,但是有一些事情可以确保您理解这样做的目的。从您的示例中:

async function test() {
    const result = await Library.functionReturningAPromise()
    const obj = new Example(result);

    // do the rest of the logic
}
  1. 所有用async声明的函数都返回一个Promise。那是您从他们那里获得的唯一一种返回值。如果调用方正在寻找返回值,或者想知道异步操作何时完成或正在寻找错误,则他们必须与.then().catch()或与{{1}一起使用返回的诺言}放在await函数中。
  2. 如果您正在等待拒绝的诺言,它将实质上抛出并中止该函数的其余执行,然后返回拒绝来返回返回的诺言。
  3. 如果您希望执行流程因被拒绝的承诺而中止,并且调用方将处理拒绝,那么就可以了。
  4. 但是,如果呼叫者没有处理拒绝,则有人需要。如果您使用的是async,并且需要在本地处理拒绝,则需要将它们包装在await中(语法与同步异常非常相似)。

以下是将try/catchtry/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/awaitthen()的组合来进行同步编程。

这是一个使用记忆来返回结果或在需要时查询它的示例:

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());