Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/474.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“减少嵌套”;如果';s";在javascript中_Javascript_Asynchronous_Callback - Fatal编程技术网

“减少嵌套”;如果';s";在javascript中

“减少嵌套”;如果';s";在javascript中,javascript,asynchronous,callback,Javascript,Asynchronous,Callback,我有三个异步运行的函数,其中返回函数是函数调用的一部分。我需要做的是“如果函数A和函数B返回一个好值(不是错误),那么就执行函数C。”我现在拥有的是“如果函数A返回一个好值,那么调用函数B,如果函数B返回一个好值,那么调用函数C。” 有没有更好的方法在javascript中实现这一点 我正在使用的代码如下: // Login to amazon // function 0 amazon.Login.authorize(options, function(authResponse)

我有三个异步运行的函数,其中返回函数是函数调用的一部分。我需要做的是“如果函数A和函数B返回一个好值(不是错误),那么就执行函数C。”我现在拥有的是“如果函数A返回一个好值,那么调用函数B,如果函数B返回一个好值,那么调用函数C。”

有没有更好的方法在javascript中实现这一点

我正在使用的代码如下:

// Login to amazon
// function 0       
amazon.Login.authorize(options, function(authResponse) {
    if ( authResponse.error ) {
        // user not logged in. Do nothing.
        alert('oauth error ' + response.error);
        return;
    }
    else
    { // good response
      // Call function A
      amazon.Login.retrieveProfile(authResponse.access_token, function(response) {
          if ( response.success ) { // good response
              // Prepare to call function B   
              // Initialize the Amazon Cognito credentials provider
              AWS.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: 'abc' });
              AWS.config.region = 'us-east-1';
              AWS.config.credentials.params.Logins = { 'www.amazon.com': authResponse.access_token };

              // Call function B. This could be called at the same time as function A                               
              AWS.config.credentials.get(function(err) {
              if (!err) {
                   // Both Function A and Function B came back with good results. 
                   // Now can call function C and do more work
              } else {
                   // error in function B
              }
          } else {
              // error in function A
          }
     }
}

您可以通过不将这些函数内联,而是在外部定义它们来降低复杂性。 在这个例子中 authorize(选项,authorizeCallback(响应))


等等,javascript将函数视为一等公民,因此您可以将它们视为值,并传递它们。

正如Gustavo所演示的,您可以定义内联函数 在外面,然后参考它。 我建议你以这个为例

但这并没有减少嵌套条件。 当然,authorize函数看起来更短,但它始终包含嵌套的条件

如果嵌套条件越来越多,那么搜索关键字应该是“异步控制流模式”。然后你会发现库,它们解决了这个异步编码的地狱

看看异步库


看起来你在建造末日金字塔。您可以通过链接承诺来避免这种情况(我已经使用了来自的polyfill)。您可以链接任意多个函数,只要它们返回承诺。此外,您可以避免
else
块字节过早抛出异常

var accessToken;

(new Promise(amazon.Login.authorize.bind(amazon.Login, options)))
    .then(function (authResponse) {
        if (authResponse.error) throw res.error;

        accessToken = authResponse.access_token;

        return new Promise(amazon.Login.retrieveProfile.bind(amazon.Login, accessToken));
    })
    .then(function (response) {
        if (!response.success) throw 'Profile retrieval failed';

        AWS.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: 'abc' });
        AWS.config.region = 'us-east-1';
        AWS.config.credentials.params.Logins = { 'www.amazon.com': accessToken };

        return new Promise(AWS.config.credentials.get.bind(AWS.config.credentials));
    })
    .then(function (err) {
        if (err) throw err;

        // call function C here
    })
    .catch(function (err) {
        // do something with error
    });
您可能需要检查您使用的API的文档。也许这些方法已经有了回报承诺的版本


演示:

对于初学者,如果您的
返回,则不需要使用
else
,因为它保证是其他的。这里有一个关于使用
promises
的不错的教程,只要您使用的是回调,这就是方法。您可以考虑使用命名函数,但本质上,这并不能帮助您得到通常称为“回调地狱”的东西。一种常见的替代方法是使用承诺,它提供了一种不同的链接调用的方法,但您仍然需要使用三个函数。“最佳”解决方案是使用async/await,但这只适用于ES7。此时,它是由一些编译成JavaScript的语言通过状态机模拟的。@BrianGlaz,你能看一下吗?嗨,Gustavo,使用这个解决方案,我仍然会调用函数a,然后调用函数a中的函数B,这是正确的吗?有没有一种方法可以处理你建议调用函数a,调用函数B,等待a和B的响应,如果两者都很好,是否继续?是的,我知道你正在尝试删除if/else,但仍然需要进行错误检查。处理大量回调的问题之一。我建议使用这种方法(代码不会杂乱无章,每个if/else都在一个单独的函数中)查看更新后的代码片段。第三种解决方案是Pubsub/Observer模式,但对于这个例子来说,这可能太多了。最佳方法是Gustavos解决方案。
var accessToken;

(new Promise(amazon.Login.authorize.bind(amazon.Login, options)))
    .then(function (authResponse) {
        if (authResponse.error) throw res.error;

        accessToken = authResponse.access_token;

        return new Promise(amazon.Login.retrieveProfile.bind(amazon.Login, accessToken));
    })
    .then(function (response) {
        if (!response.success) throw 'Profile retrieval failed';

        AWS.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: 'abc' });
        AWS.config.region = 'us-east-1';
        AWS.config.credentials.params.Logins = { 'www.amazon.com': accessToken };

        return new Promise(AWS.config.credentials.get.bind(AWS.config.credentials));
    })
    .then(function (err) {
        if (err) throw err;

        // call function C here
    })
    .catch(function (err) {
        // do something with error
    });