繁体   English   中英

Promise 嵌套在异步 function 中 - 为什么不只使用异步/等待?

[英]Promise nested inside async function - why not working only with async/await?

TL;博士

Can't get an async/await function to do what an async function achieves by returning a custom new Promise object.


我正在尝试构建一个 function ,它接受一个字符串,遍历字符串中的单词,并设置一个间隔,在您分配的设置间隔之后记录每个单词。 完成记录后,回调将记录 function 完成每个字的记录后的总字数。 下面,你有主要的 function。

async function textReader (text, callback, interval = 1000) {
  return new Promise((resolve, reject) => {
    let counter = 0
    let textArray = text.trim().split(' ')
    let idInterval = setInterval( () => {    

      if(counter == textArray.length) {
        callback(textArray.length)
        clearInterval(idInterval)
        resolve();

      } else {
        console.log(textArray[counter++])
      }
    }, interval)
  })
}

然后,记录显示字数的回调:

function funCallback (wordQuantity) {
  console.log(`Process complete - The text contains ${wordQuantity} words`)
}

最后,一个async function 测试主要 function。 它只是简单地运行了主 function 的 3 次,并按照应有的方式一个接一个地记录它们中的每一个。 这个想法是每个await都会阻塞该过程,直到有一个解析值(这实际上意味着:当它在终端中登录每个单词时),一旦await完成,跳转到下一个textReader function 等等。

async function test () {
  try {
    let time = 500
    await textReader('When I find myself in times of trouble ', funCallback, time)
    await textReader('mother Mary comes to me ', funCallback, time)
    await textReader('speaking words of wisdom Let it be', funCallback, time)
  } catch (err) { console.log(err)}
}

My issue is that I want the textReader function to be able to achieve the same behavior without having to return a new Promise , but using await (because I guess that's what an async/await function should be helpful with, right? achieve the same as一个 ES6 Promise )

请记住,整个计划的目标是:

  • 记录特定间隔中的单词
  • 如果test()持有多个textReader() ,它们必须是阻塞的,这意味着一个必须等待另一个完成记录它的单词,否则所有测试函数的单词将一个重叠 - 这将顺便说一句,非常令人困惑-。
  • 计算每个字符串中记录了多少单词。

我只是不明白如何解决它而不必从textReader()返回一个new Promise但使用await ,因为它应该在async/await function 中。

使用async/await (见下文)解决它的尝试之一没有奏效; 它只是同时运行来自test()函数的 3 个textReader() ,重叠日志。

async function textReader (text, callback, time = 1000) {
  let counter = 0
  let textArray = text.trim().split(' ')
     
  let loggingWords = async () => {
        let idInterval = setInterval( () => {    
    
          if(counter == textArray.length) {
            callback(textArray.length) 
            clearInterval(idInterval)     
          } else { 
            console.log(textoArray[contador++]) 
          } 
        }, time) 
      }

      let waitForLogingWords = await loggingWords()
      
      return waitForLogingWords
    };

如评论中所述,您无法完全避免调用new Promise() 一旦确定了这一点,我们不妨接受它。

这是“我想使用承诺按顺序处理项目列表,每个项目之间有延迟”问题的通用解决方案。

const sequence = (iterable, payload, delay=0) =>
  iterable.reduce((p, item) =>
    p.then(() =>
      new Promise(r => setTimeout(r, delay)).then(() => payload(item))
    ), Promise.resolve()
  );

它需要一个项目列表并创建一个 promise 链,每个 promise 在前一个之后完成delay毫秒。

基于此,很容易实现你的textReader - 它是一个记录每个单词的单词sequence

var textReader = (text, interval=1000) =>
  sequence(text.trim().split(' '), word => console.log(word), interval);

您的 function 再次处理歌曲只是一个多行的sequence ,因此它同样易于实现。 这次作为async function (但这只是细节 - sequence(...).then(...)会起作用):

async function test() {
  try {
    await sequence([
      'When I find myself in times of trouble ',
      'mother Mary comes to me ',
      'speaking words of wisdom Let it be'
    ], line => textReader(line, 500));
    console.log('-all done-');
  } catch (err) {
    console.log(err);
  }
}

一旦我们运行test() ,我们会得到一个整齐交错的 output 单词,每个单词间隔 1/2 秒:

When
I
find
myself
in
times
of
trouble
mother
Mary
comes
to
me
speaking
words
of
wisdom
Let
it
be
-all done-

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM