【问题标题】:How to get resolved value/rejected error in finally block?如何在 finally 块中获得已解决的值/拒绝错误?
【发布时间】:2019-08-27 02:17:53
【问题描述】:

使用 Q.js Javascript 承诺库,如何在 finally 块中获取已解决的值/拒绝的错误对象。基本上我想在 finally 块中使用传递给 then 块的解析数据执行通用代码。

var q = require('Q');

var defer = q.defer();

setTimeout(function () {
    console.log("----------------------------------");

    promise2 = defer.promise;
    var t = promise2.then(function (value) {
        console.log('defer then => ' + value);
    })
    .catch(function (err) {
        console.log('defer catch => ' + err);
    })
    .finally(function (data) {
        console.log('function pro1 : ' + defer);
        // console.log('defer finally(resolved value) => ' + data); // how to get 123 here
        // console.log('defer finally(error) => ' + data); // how to get 'Error occurred.' here
        doSomething(data);
    })

    setTimeout(function () {
        console.log('after2: ' + t);
    },2000)

    defer.resolve('123');
    defer.reject('Error occurred.');
},10);

【问题讨论】:

    标签: javascript node.js asynchronous promise q


    【解决方案1】:

    finally 是一个用于执行代码的函数,不管 promise 的解决或拒绝,代码如清理资源(关闭连接等)。因此,在需要数据的情况下使用它并不是一个好主意。另外,我不建议使用全局变量,因为这不太符合 Promise 的理念。

    如果你在 Promise 成功或失败时需要这两个值,我建议使用thencatchthen 的序列,如下所示:

    var q = require('Q');
    
    var defer = q.defer();
    
    setTimeout(function () {
        console.log("----------------------------------");
    
        promise2 = defer.promise;
        var t = promise2.then(function (value) {
            console.log('defer then => ' + value);
            return { status: "success", value: value };
        })
        .catch(function (err) {
            console.log('defer catch => ' + err);
            return { status: "err", value: err };
        })
        .then(function (dataOrError) {
            console.log('function pro1 : ' + defer);
            // console.log('defer finally(resolved value) => ' + data); // how to get 123 here
            // console.log('defer finally(error) => ' + data); // how to get 'Error occurred.' here
            doSomething(dataOrError); // Here you can check if you got an error or the value you exepected.
        })
    
        setTimeout(function () {
            console.log('after2: ' + t);
        },2000)
    
        defer.resolve('123');
        defer.reject('Error occurred.');
    },10);
    

    但是,如果你要执行代码,取决于你承诺的结果(解决或拒绝),你应该使用这个模式:

    promise.then((data) => {
       //doSomething with data
       return data;
     }).catch((err) => {
       //doSomithing with error
       return error;
     }).then((dataOrError) => {
      //doSomething with dataOrErro that does not depend if it is data or error
     });
    
    

    【讨论】:

    • 干净的解决方案和很好的解释
    【解决方案2】:

    使用await 和一个全局变量。等到 promise 得到解决,然后将检索到的值分配给全局变量,然后您可以在 final 块中访问。

    const func = () => new Promise((resolve) => {
        resolve(10);
    });
    
    let data;
    
    (async() => {
        try {
            data = await func();
        }
        catch(e) {
          // ..
        }
        finally {
            console.log(data);
        }
    })();

    【讨论】:

      【解决方案3】:

      您可以在父作用域中添加一个变量,如下所示:

      var q = require('Q');
      
      var defer = q.defer();
      
      setTimeout(function () {
          console.log("----------------------------------");
      
          var promise2 = defer.promise;
          var data = false;
          var t = promise2.then(function (value) {
              console.log('defer then => ' + value);
              data  = value;
          })
          .catch(function (err) {
              console.log('defer catch => ' + err);
          })
          .finally(function () {
              console.log('function pro1 : ' + defer);
              // console.log('defer finally(resolved value) => ' + data); // how to get 123 here
              // console.log('defer finally(error) => ' + data); // how to get 'Error occurred.' here
              doSomething(data);
          })
      
          setTimeout(function () {
              console.log('after2: ' + t);
          },2000)
      
          defer.resolve('123');
          defer.reject('Error occurred.');
      },10);

      【讨论】:

      • 这不起作用,因为它不等待承诺得到解决。
      • 这是一种简单的方法,但可能不适用于更复杂的 Promise 方法链接。此外,我正在寻找一种更优雅的解决方案,而不必在父范围内声明变量 - 它使代码更难理解。
      猜你喜欢
      • 1970-01-01
      • 2020-12-22
      • 1970-01-01
      • 2021-09-14
      • 1970-01-01
      • 1970-01-01
      • 2018-03-27
      • 1970-01-01
      • 2014-12-26
      相关资源
      最近更新 更多