【问题标题】:Passing a function directly vs anonymous function, to a then promise callback将函数直接与匿名函数传递给 then promise 回调
【发布时间】:2019-04-13 19:11:31
【问题描述】:

我试图了解这 3 个选项之间的区别:

.then(myCallback)

.then(myCallback())

.then(() => { myCallback() })

myCallback 函数不返回任何内容,仅用于它的副作用,所以我不需要它将任何东西传递回承诺链。我不明白的是为什么在我的代码中只有第二个选项触发该函数,而这三个选项似乎都应该触发。

更新:这是基本要素的代码

serverCall(url, data) // fetch function
  .then((response) => response.json())
  .then(myCallback) // not running, only when () added
  .catch((error) => { console.log(error) })

const myCallback = () => { 
  anotherServerCall(...).then(...)
}

更新 2

经过一番挖掘,我发现将.then((response) => response.json()) 作为第一个then response 是阻止.then(myCallback) 执行的原因。还是不知道为什么……

【问题讨论】:

  • 你在兑现承诺吗?第二个调用函数并将结果传递给then,这可能不是你想要的。
  • 正如@tkausl 所指出的,对于要执行的这些回调,似乎没有解决承诺。
  • then 用于fetch 所以我认为回调正在解决
  • 但是函数应该已经被调用了。选项 1 和 3 看起来不错,如果它们不被称为您的问题在其他地方。
  • 您应该将myCallback 添加到您的问题中。

标签: javascript callback promise es6-promise


【解决方案1】:

这三个都应该触发该功能,但方法之间的顺序不同。如果您有时会看到没有调用 serverCallmyCallback 的证据,那么这与这些函数的细节有关,而不是您调用它们的方式。

为了演示,请考虑serverCallmyCallback 的两个代理,我们知道它们将始终有效。让我们将您问题中的每个想法应用于那些:

  1. 这是使用then 的“正常”方式。向它传递一个函数,该函数在 它所附加的承诺之后调用......

function serverCall() {
    console.log('began server call');
    return new Promise(function(resolve) {
        setTimeout(() => {
            console.log('completed server call');
            resolve();
        }, 2);
    });
}

function myCallback() {
    console.log('callback called');
}

serverCall().then(myCallback).then(() => console.log('done'));

// produces: 
// began server call
// completed server call
// callback called
// done
  1. 您的第一个和第三个想法几乎相同。然后传递一个在promise之后调用的函数。在您的第三个想法中,该函数不是回调,而是一个调用回调的函数。多了一个堆栈帧,但效果完全相同...

function serverCall() {
    console.log('began server call');
    return new Promise(function(resolve) {
        setTimeout(() => {
            console.log('completed server call');
            resolve();
        }, 2);
    });
}
    
function myCallback() {
    console.log('callback called');
}


serverCall().then(() => { myCallback() }).then(() => console.log('done'))

// produces:
// began server call
// completed server call
// callback called
// done
  1. 正如评论者指出的那样,您的第二个想法是调用该函数并将其结果传递给thenthen 的链接在启动 Promise 后同步运行,因此结果显示为重新排序:myCallback 在 Promise 完成之前运行...

function serverCall() {
    console.log('began server call');
    return new Promise(function(resolve) {
        setTimeout(() => {
            console.log('completed server call');
            resolve();
        }, 2);
    });
}
    
function myCallback() {
    console.log('callback called');
}


serverCall().then(myCallback()).then(() => console.log('done'))

// produces:
// began server call
// callback called         <------ CHANGED!!!
// completed server call
// done

【讨论】:

  • 明白了,谢谢!尽管如此,由于某种原因,这个 .then((response) => response.json()).then(myCallback) 不会触发 myCallback。只有当我删除第一个时它才会起作用。
  • @ilyo,其中一个原因是如果 json 方法抛出错误,其余的承诺将被跳过。如果您将.catch(err =&gt; console.log(err)) 放在最后,您可能会发现执行流程在此进行
【解决方案2】:

我发现重复您的问题的唯一方法是回调是否返回一个函数。选项 1 和 3 不执行任何操作,因为没有调用返回的函数。选项 2 调用并成功。

function fetch() {
  return new Promise((resolve, reject) => {
    resolve();
  });
}

function myCallBack() {
  return function () {
    console.log('Success');
  };
}

fetch().then(myCallBack); // nothing
fetch().then(myCallBack()); // Success
fetch().then(() => myCallBack()); // nothing

【讨论】:

    【解决方案3】:

    您的用例不同,因为

    第一个then调用,你传递了一个callback在执行时调用,如果发生错误,传递一个命名函数将出现在堆栈跟踪中

    第二个,在传递给then函数之前执行传递的callback,执行回调的结果将传递给then函数,想象一下。

    function myCallback(){
            return function   theRealCallbackPassed(thenResponse){
              // do something with then response
            }
        }
    

    最后一个,会定义一个匿名箭头函数,那么两者的区别是什么

    then( () => {} )
    

    还有

    then( function(){} )
    

    不同的是,使用箭头函数() =&gt; {},你有一个简短的语法,你将函数 contexto 绑定到声明它的箭头函数的当前上下文。

    虽然function() {} 语法不短且不能自动绑定。

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-18
      相关资源
      最近更新 更多