JS ES6 Promise Chaining

时间:2016-02-29 22:33:52

标签: javascript promise chaining es6-promise

我试图学习如何使用承诺,但我很难理解链接。我假设使用此代码,两个承诺都将运行。然后,当我调用test.then()时,它应该知道测试已经解决并将解析数据传递给then()。

一旦该函数完成,它将进入下一个then(),并使用test2 promise重复相同的过程。

但是,我只能打印出第一个承诺结果,而不是第二个。这里缺少什么想法?

var test = new Promise(function(resolve, reject){
    resolve('done1');
});

var test2 = new Promise(function(resolve, reject){
    resolve('done2');
});

test
.then(function(data) {
    console.log(data);
})
.then(test2)
.then(function(data) {
    console.log(data);
});

5 个答案:

答案 0 :(得分:16)

您的第一个.then来电正在返回undefined,而后续的任何.then预计会返回一个承诺。因此,您需要将代码更改为:

var test = new Promise(function(resolve, reject){
    resolve('done1');
});

var test2 = new Promise(function(resolve, reject){
    resolve('done2');
});

test
.then(function(data) {
    console.log(data);
    return test2;
})

.then(resultOfTest2 => doSomething)
.then(function(data) {
console.log(data);
});

答案 1 :(得分:3)

您需要从then回调中返回下一个承诺:

test.then(function(data) {
    console.log(data);
    return test2;
}).then(function(data) {
    console.log(data);
});

答案 2 :(得分:2)

你需要在第一个promise(test1)中返回另一个promise(test2)以允许链接:

  var test = new Promise(function(resolve, reject){
    resolve('done1');
});

var test2 = new Promise(function(resolve, reject){
    resolve('done2');
});

test
.then(function(data) {
  console.log(data);
  return test2;
});

答案 3 :(得分:1)

摘要:

使用诺言链接诺言的基本概念是,已实现诺言中的每个then / catch方法都会返回另一个诺言。它以以下方式工作:

  • 解决承诺后,将调用在then方法中传递的回调。 then方法将在其回调中返回的值包装在已解决的承诺中,并返回此已解决的承诺
  • 当拒绝承诺时,将调用catch方法中传递的回调。 catch方法将在其回调中返回的值包装在被拒绝的承诺中,并返回此被拒绝的承诺

示例:

在充分理解链接多个then方法的概念之前,重要的是要知道thencatch的返回值到底是什么。请看以下示例:

let prom1 = new Promise((res, rej) => {
  res('res');
});

const resolvedProm1 = prom1.then((val) => {return val});
// setTimeout needed for the promise to actually be resolved
setTimeout(() => console.log(resolvedProm1));

let prom2 = new Promise((res, rej) => {
  rej('rej');
});

const resolvedProm2 = prom2.catch((err) => {throw err});
// setTimeout needed for the promise to actually be rejected
setTimeout(() => console.log(resolvedProm2));

我们可以在chrome devtools中观察诺言的状态:

promises javascript

基本上发生的是在thencatch回调中是以下内容:

  • thencatch回调中返回的任何值都包装在Promise.resolve()中,并返回新的 resolved 承诺。
  • thencatch回调中引发的任何错误都包装在Promise.reject()中,并返回新的 rejected 承诺。

由于我们将返回被拒绝或已解决的Promise对象,因此可以重复该循环并对其再次调用thencatch方法。例如:

const prom = new Promise((res, rej) => {
  if (Math.random() > 0.5) {
    res('success');
  } else {
    rej('error');
  }
});

prom.then((val) => {
  return val;
}).then((val) => {
  return val
}).then((val) => {
  console.log(val)
}).catch((err) => {
  console.log('err');
})

以各自的顺序执行的thencatch方法的这种调用称为“承诺链”。简化异步代码的使用是一项非常有用的技术,尤其是在需要执行依赖于彼此数据的多个异步操作时。

答案 4 :(得分:0)

您可能还想尝试 -

    let test = new Promise(function(resolve, reject){
        resolve('done1');
    });

    let test2 = new Promise(function(resolve, reject){
        resolve('done2');
    });

    try {
        let logOne = test();
        let logTwo = test2();
        console.log(logOne);
        console.log(logTwo);
    } catch(error) {
        console.error(error);
    }

通过这种方式,您还可以正确处理任何promise依赖项。例如,如果测试者依赖于测试二的数据,你可以 -

try {
        let logOne = test();
        let logTwo = test2(logOne);
        console.log(logOne);
        console.log(logTwo);
    } catch(error) {
        console.error(error);
    }