【问题标题】:javascript async: Log the response from each action in the order it was calledjavascript async:按调用顺序记录每个操作的响应
【发布时间】:2018-12-23 09:41:18
【问题描述】:

我正在努力解决 JS 异步问题,并且正在努力解决以下面试练习问题,你们中的一些人可能会对此有所了解。

鉴于以下提供的功能(我们不允许更改):

    function processAction(i, callback) {
     setTimeout(function() {
       callback("Processed Action " + i);
     }, Math.floor(Math.random()*1000));
   }

编写函数triggerActions(count)(必须调用proccessAction)和callback(message)函数,以便triggerActions(3)记录以下内容: Processed Action 1 Processed Action 2 Processed Action 3

在不更改processAction 函数的情况下,我无法弄清楚如何让我的操作按照它们开始时的顺序登录。我也不确定如何实现一个允许我对任意数量的操作执行此操作的函数。我设法最接近正确功能的方法如下所示:

const printString = (x) => {
  return new Promise((resolve, reject) => {
    let time = Math.floor(Math.random()*1000);
    setTimeout(() => {
      console.log(`${x} is resolved after ${time}.`);
      resolve();
    }, time);
  });
}
async function printAsync() {
  await printString('a');
  await printString('b');
  await printString('c');
};

产生:

a is resolved after 431.
b is resolved after 149.
c is resolved after 798.

目前参考的资源:

--callbacks/promises/await

--understanding async/await

【问题讨论】:

    标签: javascript asynchronous callback promise


    【解决方案1】:

    (我们不允许更改):

    然后你可以做的是创建一个包装函数。

    例如。

    function processAction(i, callback) {
      setTimeout(function() {
        callback("Processed Action " + i);
      }, Math.floor(Math.random()*1000));
    }
    
    function processActionWrap(i) {
      return new Promise((resolve, reject) => {
        processAction(i, function (str) {
          console.log(str);
          resolve(str);
        });
      });
    }
    
    async function test() {
      await processActionWrap(1);
      await processActionWrap(2);
      await processActionWrap(3);
    }
    
    test();

    【讨论】:

      【解决方案2】:

      Keith 的回答让我实现了以下似乎可以正常工作的内容:

      async function triggerActions(count) {
        let i = 1;
        for (i; i <= count; i++) {
          await processActionWrap(i);
        }  
      }
      
      function processAction(i, callback) {
        let time = Math.floor(Math.random()*1000);
        setTimeout(function() {
          callback(`Processed Action ${i} in ${time}`);
        }, time);
      }
      
      function processActionWrap(i) {
        return new Promise((resolve, reject) => {
          processAction(i, (str) => {
            console.log(str);
            resolve(str);
          });
        });
      }
      
      triggerActions(5);
      

      输出:

      Processed Action 1 in 841
      Processed Action 2 in 15
      Processed Action 3 in 346
      Processed Action 4 in 331
      Processed Action 5 in 314
      

      再次感谢!

      【讨论】:

        【解决方案3】:

        你可以使用一些柯里化:

        const trigger = (fn, max, count = 1) => () => max <= count && fn(count, trigger(fn, count + 1));
        
        const triggerActions = max => trigger(cb => processAction(res => (console.log(res), cb()), 3)();
        

        ...但在一次采访中,我不会试图用函数式编程来给人留下深刻印象,而是宁愿将processAction 包装成一个承诺:

        const triggerAction = i => new Promise(res => processAction(i, res));
        

        那么你可以很容易地await,即使是在循环中......

        【讨论】:

          猜你喜欢
          • 2011-09-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-16
          • 1970-01-01
          • 2013-09-14
          • 1970-01-01
          相关资源
          最近更新 更多