代码之家  ›  专栏  ›  技术社区  ›  guijob

如何从一个承诺中返回然后阻止?

  •  1
  • guijob  · 技术社区  · 6 年前

    我想知道 promise 的级联正常工作。为此,我创建了一个函数,它返回一个新的 Promise 但是有一些 callback functions 在其范围内:

    exports.function1 = (params) => {
      return new Promise((resolve, reject) => {
        // do something sync
    
        someFunctionAsyncWithCallback(params, (err, data) => { //async func
          err ? reject(err) : resolve(data);
        })
      }).then(data => {
         // do something sync again
    
        anotherAsyncFunctionWithCallback(data, function (err, response) {
          return err ? Promise.reject(err) : Promise.resolve(response);
          // return err ? reject(err) : resolve(response); ?
        });
      })
    }
    

    在…内 then 布洛克,我怎样才能 return 为了继续级联过程?在里面 executor 我可以调用一些解析/拒绝函数来继续链接。但是,一旦我们进入 然后 执行时,这些函数不存在-如果我错了,请纠正我-我不知道如何继续。

    如有任何意见,将不胜感激。

    3 回复  |  直到 6 年前
        1
  •  5
  •   T.J. Crowder    6 年前

    避免将承诺链与回调风格的API相结合。相反,使用promise包装器包装回调风格的API,这样就可以合理地组合内容。

    您引用的示例看起来像NodeJS API。如果您使用的是Node,v8及更高版本 utils.promisify 它可以用于快速轻松地将标准NodeJS回调风格的函数包装为返回承诺的函数。

    // Get promise-enabled versions:
    const promiseSomeFunctionAsyncWithCallback = utils.promisify(someFunctionAsyncWithCallback);
    const promiseAnotherAsyncFunctionWithCallback = utils.promisify(anotherAsyncFunctionWithCallback);
    
    // Use them:
    exports.function1 = (params) => {
      return promiseSomeFunctionAsyncWithCallback(params)
        .then(promiseAnotherAsyncFunctionWithCallback);
      })
    };
    

    如果您没有使用Node,或者使用的是旧版本,那么 UTIL。承诺 ,您可以轻松推出自己的:

    const promisify = f => return function(..args) {
        return new Promise((resolve, reject) => {
            f.call(this, ...args, (err, result) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(result);
                }
            });
        });
    };
    

    回复您的评论:

    我在这些回调函数之间有一些同步代码。。在第一个示例中,您将如何处理它?

    有两种风格:

    1、将同步代码放入 then 只有在到达下一个异步位时才进行回调和链:

    exports.function1 = (params) => {
      // Code here will run synchronously when `function1` is called
      return promiseSomeFunctionAsyncWithCallback(params)
        .then(result => {
            // You culd have synchronous code here, which runs when
            // this `then` handler is called and before we wait for the following:
            return promiseAnotherAsyncFunctionWithCallback(result);
        });
      })
    };
    

    2、将同步代码放在自己的 然后 回调:

    exports.function1 = (params) => {
      // Code here will run synchronously when `function1` is called
      return promiseSomeFunctionAsyncWithCallback(params)
        .then(result => {
            // You culd have synchronous code here, which runs when
            // this `then` handler is called.
            // Pass on the result:
            return result;
        })
        .then(promiseAnotherAsyncFunctionWithCallback);
      })
    };
    

    #2的一个优点是,每个不同的逻辑步骤都是自己的块。这确实意味着在主事件循环的迭代结束时,会有一个额外的收益返回到微任务循环,但这不太可能是一个问题。

        2
  •  3
  •   Jonas Wilms    6 年前

    您需要回报另一个承诺:

    return new Promise((res, rej) => anotherAsyncFunctionWithCallback(data, (err, data) => err ? rej(err) : res(data));
    

    然而,有必要承诺该功能:

     const promisify = f => (...args) => new Promise((res, rej) => f(...args, (err, data) => err? rej(err) : res(data)));
    
    const asyncF = promisify(AsyncFunctionWithCallback);
    

    因此,我们可以:

    asyncF(1).then(asyncF).then(console.log);
    
        3
  •  0
  •   tester01    3 年前

    您可以使用标志变量返回某些内容。

    实例

    async function test(){
       let flag=0;
       await fetch(request).then(()=> flag=1}
       if(flag==1) return;
    }