使用 Promise 按顺序调用函数

Using Promises to Call Functions In Sequence

我有以下代码,由三个函数和一个回调函数组成。 我在这里面临的挑战是: 我必须按此顺序打印 A ,然后是 B ,然后是 C

我试过下面的代码,但它总是打印 C 、 B ,然后是 A

我知道这是由于 setTimeout A > setTimeout B > setTimeout C 造成的。

但是有什么办法可以让我只有在得到A的响应时才调用B,只有在得到B的响应时才调用C。

请帮忙,因为我被困在这里

const print = (err, contents) => { 
  if (err) console.error(err)
  else console.log(contents) 
}

const opA = (cb) => {
  setTimeout(() => {
    cb(null, 'A')
  }, 500)
}

const opB = (cb) => {
  setTimeout(() => {
    cb(null, 'B')
  }, 250)
}

const opC = (cb) => {
  setTimeout(() => {
    cb(null, 'C')
  }, 125)
}

我试过的代码:

function promisifyA(){
    return new Promise( (resolve,reject) => {
      resolve(opA(print));
    });
}

function promisifyB(){
  return new Promise( (resolve,reject) => {
    resolve(opB(print));
  });
}


function promisifyC(){
  return new Promise( (resolve,reject) => {
    resolve(opC(print));
  });
}


promisifyA().then(() => {
  return promisifyB();
}).then(() => {
  return promisifyC();
});

你应该只在函数完成后才 resolve() 。 即

function promisifyA(){
    return new Promise( (resolve,reject) => {
      opA((err, val) => { 
            print(val); 
            resolve()
        });
    });
}

在第一种(非承诺)方法中,我想你是这样调用你的函数的:

opA(print);
opB(print);
opC(print);

很明显,所有三个函数 opAopBopC 都被一个接一个地立即调用。以下是如何将它们作为您传递的回调 的 一部分进行调用:

const print = (err, contents) => { 
  if (err) console.error(err)
  else console.log(contents) 
}

const opA = (cb) => {
  setTimeout(() => {
    cb(null, 'A')
  }, 500)
}

const opB = (cb) => {
  setTimeout(() => {
    cb(null, 'B')
  }, 250)
}

const opC = (cb) => {
  setTimeout(() => {
    cb(null, 'C')
  }, 125)
}

opA((err, contents) => {
    print(err, contents);
    opB((err, contents) => {
        print(err, contents);
        opC(print);
    });
});

虽然这会实现你想要的,但这也导致了所谓的“回调地狱”。如果你重复这个模式,缩进只会不断增加...

这就是 promises 可以提供帮助的地方。首先承诺 setTimeout:

const delay = (ms, value) => new Promise(resolve => 
    setTimeout(() => resolve(value), ms)
);

const output = console.log;
const error = console.error;
const opA = () => delay(500, 'A');
const opB = () => delay(250, 'B');
const opC = () => delay(125, 'C');

opA().then(output)
     .then(opB)
     .then(output)
     .then(opC)
     .then(output)
     .catch(error);