【问题标题】:Promise.resolve - Unexpected resultPromise.resolve - 意外结果
【发布时间】:2019-03-23 20:05:48
【问题描述】:

我不明白 Promise。我知道 Promises 是可以成功或错误地完成的对象。 Promise 可以很好地执行异步函数并通过then 连接其他异步函数。 Promise 的结果作为参数传递给最后执行的 Promise 的 then 方法内的回调函数(如果 Promise 正确结束)。

这个例子不起作用。我正在通过 setTimeout 模拟异步调用。我的函数返回一个整数。我希望得到 5 作为prom2 的结果。为什么不起作用?我做错了什么,为什么?

var getProductId = function(){
    setTimeout(function () {
        return 5;
    }, 1500);
};
var prom2 = Promise.resolve(getProductId);

prom2.then(function(result){
    console.log("5 = " + result);
});

我也试过了:

var getProductId = function(){
    setTimeout(function () {
        return 5;
    }, 1500);
};
var prom2 = Promise.resolve(getProductId());

prom2.then(function(result){
    console.log("5 = " + result);
});

注意:我想使用Promise.resolve 而不是new Promise

【问题讨论】:

  • Promise.resolve 使同步代码表现得异步,它创建一个立即解决的承诺,无论你给它什么值。它不能与异步代码一起使用。即使你不想,你也应该使用new Promise

标签: javascript typescript es6-promise


【解决方案1】:

Promise.resolve 所做的只是接受一个 表达式 并将其转换为立即解析为该表达式的 Promise。如果表达式是除Promise 之外的任何类型的普通值(原始值、数组、对象等)其他,则Promise.resolve 返回的Promise 仍将立即解析。您的 getProductId 函数没有返回任何内容,因此您的 prom2 导致 Promise 立即解析为 undefined 的值。

Promise.resolve 对您的情况没有帮助 - 您需要将回调转换为 Promise,而唯一的方法是使用 new Promise 构造函数:

console.log('start');
const getProductId = () => new Promise(res => setTimeout(res, 1500, 5));
getProductId().then(res => console.log(res));

使用Promise.resolve 的时间是如果您已经有一个值(同步)并且想要将其转换为可以调用.thenPromise。例如,通过在下面的代码中使用Promise.resolve('begin')作为累加器的初始值,可以用reduce构造一个简单的Promise链:

const prom = ['foo', 'bar', 'baz']
  .reduce((lastProm, str) => (
    lastProm.then((lastStr) => {
      console.log(lastStr);
      return str;
    })),
    Promise.resolve('begin')
  );
  
prom.then((lastStr) => {
  console.log(lastStr);
  console.log('end');
});

【讨论】:

    【解决方案2】:

    Promise.resolve()

    Promise.resolve(value) 方法返回使用给定值解析的Promise 对象。如果该值是一个承诺,则返回该承诺;如果该值是一个 thenable(即有一个 "then" method),返回的 promise 将“跟随”该 thenable,采用它的最终状态;否则返回的 Promise 将用该值实现。此函数将嵌套的类似 Promise 对象的层(例如,解析为解析为某物的 Promise 的 Promise)扁平化为单层。

    所以,基本上函数Promise.resolve 正在返回getProductId 的结果,即undefined。如果要得到结果5,则需要使用new Promise构造函数。

    这段代码sn-p显示了getProductId的结果(55)来演示Promise.resolve的用法。

    var getProductId = function() {
      setTimeout(function() {
        return 5;
      }, 1500);
      
      return 55
    };
    var prom2 = Promise.resolve(getProductId());
    
    prom2.then(function(result) {
      console.log("55 = " + result);
    });

    【讨论】:

      猜你喜欢
      • 2012-10-09
      • 2018-09-04
      • 2017-06-02
      • 2021-11-11
      • 1970-01-01
      • 1970-01-01
      • 2014-03-21
      • 2011-09-15
      • 2012-04-02
      相关资源
      最近更新 更多