javascript 如何在finally块中获得resolved value/rejected error?

nx7onnlm  于 2023-09-29  发布在  Java
关注(0)|答案(4)|浏览(101)

使用Q.js JavaScript promise库,我如何在finally块中获得resolved value/rejected error对象。基本上,我想用传递给then块的解析数据在finally块中执行通用代码。

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);
4si2a6ki

4si2a6ki1#

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的结果(resolved或rejected),你应该使用这个模式:

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
 });
tzcvj98z

tzcvj98z2#

你可以在父作用域中添加一个变量,像这样:

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);
tp5buhyn

tp5buhyn3#

使用await和全局变量。等待promise被解析,然后将检索到的值赋给全局变量,然后您可以在final块中访问该全局变量。

const func = () => new Promise((resolve) => {
    resolve(10);
});

let data;

(async() => {
    try {
        data = await func();
    }
    catch(e) {
      // ..
    }
    finally {
        console.log(data);
    }
})();
643ylb08

643ylb084#

当使用现代的async/await语法时,我通过在我的async方法周围创建一个 Package 函数并在 Package 函数中处理结果来解决这个问题。
(As其他答案提到,finally用于清理,而不是用于处理等待的结果)。
这段代码(旧):

export async function doAsync(): Promise<string> {
  try {
    if (...) {
      return Promise.resolve("hello");
    }
    if (...) {
      return Promise.resolve("world");
    }
    if (...) {
      return Promise.reject("error");
    }
  } finally {
    console.log("doAsync complete");
  }
}

已更改为此代码(新):

async function _doAsync(): Promise<string> {
    if (...) {
      return Promise.resolve("hello");
    }
    if (...) {
      return Promise.resolve("world");
    }
    if (...) {
      return Promise.reject("error");
    }
  }
}
export async function doAsync(): Promise<string> {
  try {
    const result = await _doAsync();
    console.log("doAsync complete with result: ", result);
  } catch (error) {
    console.log("doAsync failed with error: ", error);
  } finally {
    // keep this block for some cleanup if need it
  }
}

PS.注意,我们只导出doAsync Package 器,并将_doAsync保持为私有/内部方法。

相关问题