理解 .then() ES6

Understanding .then() ES6

我 运行 发现了我代码中的一个错误,这个错误困扰了我很长时间,我正在寻找一些解释。

在此代码中,注释掉的内部承诺导致了问题。一旦 setTimeout 命中,最后的 Promise.all() 就会继续,而不是在超时内解决之后。

用 promise 包装异步代码修复了流程问题,但这是为什么呢?

本质上,为什么我们不能 运行 .then() 链中的普通异步代码,一个 return 异步回调末尾的 Promise.resolve() ?

var asyncPromise = function() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            console.log('Async Promise done');
            resolve();
        }, 1000);
    });
};

var generateSignupPromises = function(qty) {
    var promiseArray = [];
    for (var i = 1; i <= qty; i++) {
        promiseArray.push(
            function() {
                return asyncPromise()
                .then(function() {
                    console.log('Before Timeout');

                  //Uncommenting this fixes the issue
                  //return new Promise(function(resolve, reject) {
                        setTimeout(function() {
                            console.log('After Timeout');
                            //resolve();
                            return Promise.resolve();
                        }, 500);
                  //})
                });
            }
        );
    }
    return promiseArray;
};

var test = generateSignupPromises(1);

Promise.all([test[0]()])
.then(function() {
    console.log('Done');
});

Link转运行宁码:http://www.es6fiddle.net/imfdtuxc/

Then 是一个同步函数,所以如果你想在 then 中执行异步任务,你必须 return 一个 Promise。

此外,Promise.all 期待一系列承诺。不是数组的数组。

var asyncPromise = function() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      console.log('Async Promise done');
      resolve();
    }, 1000);
  });
};

var generateSignupPromises = function(qty) {
  var promiseArray = [];
  for (var i = 1; i <= qty; i++) {
    promiseArray.push(
      function() {
        return asyncPromise()
        .then(function() {
          console.log('Before Timeout');

          //Uncommenting this fixes the issue
          return new Promise(function(resolve, reject) {
          setTimeout(function() {
            console.log('After Timeout');
            resolve();
            //return Promise.resolve();
          }, 500);
          })
        });
      }
    );
  }
  return promiseArray;
};

var test = generateSignupPromises(1);

Promise.all([test[0]()])
.then(function() {
  console.log('Done');
});

http://www.es6fiddle.net/imfe2sze/

why can't we just run normal async code in a .then() chain, an return a Promise.resolve() at the end of the async callback?

你完全可以。但是任何值——无论是 promise 还是其他什么——从一个普通的异步回调中 returned 都会像往常一样被忽略

then 回调中启动异步操作没有任何改变,setTimeout 只是 return 没有承诺 - then 赢了不知道它可以等待的任何异步事件。

如果你想 return 从一个回调中得到一个承诺并得到另一个最终结果的承诺,它必须是一个 then 回调:

asyncPromise()
.then(function() {
    return new Promise(function(resolve, reject) {
//  ^^^^^^
        setTimeout(resolve, 500);
    }).then(function() {
//     ^^^^^^^^^^^^^^^
        return Promise.resolve();
    });
});