【问题标题】:how can we combine synchronous function, callback function and promise all together我们如何将同步函数、回调函数和 Promise 组合在一起
【发布时间】:2021-07-06 22:10:34
【问题描述】:

如果我有三种类型的函数,分别返回,

  1. 一个同步值:
    function a(){
      return 'a';
    }
    
  2. 回调:
    function b(callback){
      setTimeout(() => {
        callback('b');
      }, 10);
    }
    
  3. Promise:
    function c() {
      return Promise.resolve('c')
    }
    

如何将所有 3 个结果合并到一个 Promise 中?我可以创建一个返回['a', 'b', 'c'] 的函数吗?我不想改变这三个功能。

我们如何将同步函数、回调函数和Promise 组合在一起?

【问题讨论】:

  • 你想在这里解决什么问题?从您对CertainPerformances 答案的评论中,为什么将回调函数包装在Promise 中会有限制?这个问题缺乏背景。
  • 我建议您阅读Promises。

标签: javascript asynchronous promise callback synchronous


【解决方案1】:

Promisify 回调,并通过Promise.all 发送所有三个。

function a() {
  return "a";
}
function b(callback) {
  setTimeout(() => {
    callback('b');
  }, 10);
}
const bProm = () => new Promise(b);
function c() {
  return Promise.resolve('c')
}


Promise.all([
  a(),
  bProm(),
  c(),
])
  .then((results) => {
    console.log(results);
  });

【讨论】:

  • 也不要将 b 转换为 promise。它应该是回调类型。
  • 这不起作用new Promise(b);。它不会等待 setTimeout 执行回调来解决承诺。
  • @wladimirguerra 是的,你自己试试吧。将 10 更改为 3000,您会看到记录需要 3 秒而不是无记录。
  • 你是对的,它会起作用的。但并不像预期的那样。 callback 适合哪里? callback arg 必须是除了承诺 resolve 之外的另一个函数。
  • @wladimirguerra 我认为没有必要将回调包装在 another 回调中 - 鉴于问题中的代码,const bProm = () => new Promise(b); 确实足以产生预期的结果.看起来很奇怪,但考虑到 b 函数的公式,它会起作用。
【解决方案2】:

给定功能:

function a(){
  return 'a';
}

function b(callback){
  setTimeout(() => {
    callback('b');
  }, 10);
}

function c() {
    return Promise.resolve('c');
}

您可以使用Promise.all() 将它们全部包装在一个promise 中。解决方案将取决于您的要求和限制。

function b(callback) 必须被包装或更改以完成此操作,因为其中包含一个 setTimeout

包装版

function bWrapped (callback) {
    return new Promise( 
       resolve => 
          b(()=> { 
              resolve(callback('b'));
          }
    )
}

返回预期结果的函数如下:

const abc = () => {
   const functionAPromise = Promise.resolve(a())

   const callback = function(b){return b}
   const functionBPromise = bWrapped(callback)

   return Promise.all([functionAPromise,functionBPromise,c()])
}

更改的版本


function b(callback){
   return new Promise(resolve => setTimeout(()=> resolve(callback('b')), 10))
}

返回预期结果的函数如下:

const abc = () => {
   const functionAPromise = Promise.resolve(a())

   const callback = function(b){return b}
   return Promise.all([functionAPromise,b(callback),c()])
}

【讨论】:

    【解决方案3】:

    只需检查每个函数的结果并处理它们。

    function a() {
        return "a";
    }
    
    function b(callback) {
        setTimeout(() => callback("b"), 10);
    }
    
    function c() {
        return Promise.resolve("c");
    }
    const functionList = [a, b, c];
    
    function runFunctionList(list, callback) {
        const resultList = [];
        const called = {};
        function next() {
            if (resultList.length === list.length) {
                for (let i = 0; i < resultList.length; i++) {
                    if (resultList[i] === undefined) {
                        return;
                    }
                }
                callback(resultList);
                resultList.length = 0;
            }
        }
        list.forEach((li, index) => {
            const ret = li(value => {
                resultList[index] = value;
                next();
            });
            if (ret instanceof Promise) {
                // it's promise
                ret.then(value => {
                    resultList[index] = value;
                    next();
                });
            } else if (ret === undefined) {
                // it's callback function
            } else {
                // it's synchronous function
                resultList[index] = ret;
            }
        });
        next();
    }
    runFunctionList(functionList, allValue => {
        console.log("allValue here:", allValue);
    });

    【讨论】:

      【解决方案4】:

      顺序执行:

      function a() {
          return 'a';
      }
      
      function b(callback) {
          setTimeout(() => {
              callback('b');
          }, 10);
      }
      
      function c() {
          return Promise.resolve('c');
      }
      
      function abc() {
          return new Promise(resolve => {
              const valueA = a();
              b(valueB => {
                  c().then(valueC => {
                      resolve([valueA, valueB, valueC]);
                  });
              });
          });
      }
      
      abc().then(result => {
          console.log(result);
      });

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-19
        • 1970-01-01
        • 2019-04-01
        • 2018-05-30
        • 2016-10-09
        • 2015-10-15
        • 2023-03-08
        • 2016-06-01
        相关资源
        最近更新 更多