承诺链如何在不被消费/履行的情况下回归?

时间:2018-03-19 13:59:53

标签: javascript node.js asynchronous promise reduce

我对以下代码的工作方式感到困惑。 我希望在Promise.resolve()之后返回一个已解决的promise - 而不是一个挂起的promise - .then()会立即使用它/实现它,意思是; 在每个减少回调调用中,将会询问两个问题(承诺链) - 但事实上它们都是链接的,只有在从函数链返回时才会返回,它们是否相互消耗并一起运行。

这是因为我们正在等待调用堆栈'要清空并且每个.then()等待前一个.then()回调结束,所以它返回一个promise等等? 减少如何发挥作用?

有人可以帮助我更好地理解代码及其背后的概念吗?



var fs = require("fs");
var readline = require("readline");

var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
let questionsData = []; 

promisifyQuestion('How many languages do you know? \n')
  .then((numOfLanguauges) => {
    return chainPromises(numOfLanguauges)
  })
  .then((data) => {
    fs.writeFile("./langs.json", JSON.stringify(questionsData), () => {});    
    return promisifyQuestion('Display lang?');    
  })
  .then(x => {    
    console.log(JSON.stringify(questionsData.find(el => el.name == x)));    
    rl.close();
  });

  
function promisifyQuestion(msg) {    
  return new Promise((resolve, reject) => {
    rl.question(msg, resolve);    
  });
}

function chainPromises(length) {
  for (var i = 0; i < length; questionsData[i++] = {});

  let singleValue = questionsData.reduce(outerReduce, Promise.resolve()); 
//Promise chain does fire only on chainPromises end
  return singleValue;
}

function outerReduce(prevRes, currentElement, currentIndex) {
  return prevRes
    .then(() => promisifyQuestion('language name:'))
        .then(x => {    
      questionsData[currentIndex].name = x; 
              
      return promisifyQuestion('years of speaking it:');        
    })
    .then(x => {
      return questionsData[currentIndex].years = x
    });
}
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

Promises等到JavaScript调用堆栈为空。下面的代码段打印1 2 3,表示.then回调未立即运行。从技术上讲,它们是在微任务队列中安排的,与事件循环分开。

console.log('1');
Promise.resolve().then(()=>console.log('3'));
console.log('2');

你的例子更长,更复杂,但归结为此。

一些阅读材料:

答案 1 :(得分:1)

  

Promise.resolve()会返回已履行的承诺 - 而不是待定承诺 - .then()会立即使用它

是的,这是正确的。

  

在每个reduce回调调用中,将会询问两个问题(承诺链)

没有。只有链中的第一个 then回调才会立即调用。其他then调用不在初始Promise.resolve()值上,而是在先前返回的值上。那些立即履行,他们解决并等待then回调返回的承诺。