承诺如何运作?

时间:2018-06-16 07:50:42

标签: javascript es6-promise

我正在尝试使用promise打印序列中的所有异步调用。但我不明白是否隐含地返回一个承诺,或者我们应该明确地返回它。

 function fakeAjax(url,cb) {
        var fake_responses = {
          "file1": "The first text",
            "file2": "The middle text",
            "file3": "The last text"
        };
        var randomDelay = (Math.round(Math.random() * 1E4) % 8000) + 1000;

        console.log("Requesting: " + url);

        setTimeout(function(){
            cb(fake_responses[url]);
        },randomDelay);
    }

    function output(text) {
        console.log(text);
    }

    // **************************************

    function getFile(file) {
        return new Promise((resolve, reject)=>{
            fakeAjax(file,resolve);
        })
    };


    let p1= getFile('file1');
    let p2= getFile('file2');
    let p3= getFile('file3');
    p1.then(output)  // how does this code work? output doesn't return any promise, but  still we can chain it with next .then()
    .then( ()=> p2)
    .then(output)
    .then(()=>p3)
    .then(output)
    .then(()=>output('complete'))

1 个答案:

答案 0 :(得分:1)

then返回一个承诺,使您能够以这种方式链接函数。它隐式转换将output的返回值作为下一个分辨率,然后在下一个时间使其可用。在您的情况下,它将是undefined

以下是对您的代码段的轻微修改,其中我展示了then如何使您能够根据最后承诺的分辨率的返回值动态创建新的Promise

此处,在output方法中,在console.log之后,我返回了值。尝试运行代码段以查看它的实际效果。

function fakeAjax (url, cb) {
  var fake_responses = {
    'file1': 'file2',
    'file2': 'file3',
    'file3': 'The last text'
  }
  var randomDelay = 500

  console.log('Requesting: ' + url)

  setTimeout(function () {
    cb(fake_responses[url])
  }, randomDelay)
}

function output (text) {
  console.log(text)
  return text; // return the value
}

// **************************************

function getFile (file) {
  console.log('creating prommise for', file)
  return new Promise((resolve, reject) => {
    fakeAjax(file, resolve)
  })
}

var p1 = getFile('file1')
p1.then(output)
  .then(getFile)
  .then(output)
  .then(getFile)
  .then(output)

来自documentation

  

then()方法返回一个Promise。它最多需要两个参数:Promise的成功和失败案例的回调函数。

     

如果省略了一个或两个参数或提供了非函数,那么将丢失处理程序,但不会产生任何错误。如果随后被调用的Promise采用一个状态(履行或拒绝),然后没有处理程序,则创建一个没有其他处理程序的新Promise,只需采用原始Promise的最终状态,然后调用该状态。