【问题标题】:Why doesn't this test with promises pass?为什么这个带有承诺的测试没有通过?
【发布时间】:2015-04-19 01:19:34
【问题描述】:

几天前我进入了 Promises 的奇妙世界,我只是觉得自己开悟了。 Promise 看起来很简单,但它们可能会令人困惑。

你能告诉我为什么下面的测试没有通过吗?

var Promise = require('bluebird');
var expect = require('chai').expect;
var request = Promise.promisifyAll(require('request'));

describe('Promise', function() {
    it('should work again', function() {

        var final_result;

        function first_promise() {
            return new Promise(function(resolve, reject) {
                resolve("http://www.google.com");
            })
        }

        function second_promise() {
            return new Promise(function(resolve, reject) {
                resolve("This is second promise!");
            })
        }

        function inner_async_request(url_from_first_promise) {
            return new Promise(function(resolve, reject) {
                return request.getAsync(url_from_first_promise).spread(function(response, content) {
                    final_result = content;
                    resolve(content);
                })
            })
        }

        return request.getAsync('http://127.0.0.1:3000/').spread(function(result, content) {
                //do something with content and then return first_promise
                console.log(content);
                return first_promise;
            })
            .then(function(url) {
                inner_async_request(url).then(function(result) {
                    console.log(result);
                    final_result = result;
                })
                return second_promise;
            })
            .then(function(result) {
                // result should be "This is second promise!"
                console.log(result);
                // final_result should be google's html
                expect(final_result).not.to.be.undefined;
            })
    });
});

目前的错误是:Unhandled rejection Error: options.uri is a required argument 我猜应该是从first_promise 收到的?

实际上,通过这个测试,我想了解如何使用相互依赖的 Promise 以及如何将 Promise 用作 Promise 中的异步函数——它们应该单独工作——。

谢谢

【问题讨论】:

  • 您是否在实际代码中调用first_promise?返回时您仍然需要致电first_promise
  • 感谢Bergi的推荐!我看过你的那个帖子,但不能好,现在我明白了。但还不是最好的。更好:)

标签: javascript node.js asynchronous promise bluebird


【解决方案1】:

你需要调用函数来返回承诺,比如

 return request.getAsync('http://localhost:3000/').spread(function(result, content) {
         //do something with content and then return first_promise
         console.log(content);
         return first_promise();
     })

在某些情况下,您根本不需要创建新的 Promise

例如。

function inner_async_request(url_from_first_promise) {
    return request.getAsync(url_from_first_promise).spread(function(response, content) {
        final_result = content;
        return content;
    })
}

最后,为了让你的测试工作,你也需要修改它

    .then(function(url) {
        // return 
        return inner_async_request(url).then(function(result) {
            console.log(result);
            final_result = result;
            return second_promise(); // return second promise inside then
        })
    })

DEMO

【讨论】:

  • 是的,测试通过了,但我仍有一些顾虑。在这个解决方案中,return second_promise(); 不是依赖于inner_async_request() 的执行吗?我希望 inner_async_request 异步且独立地执行。
  • 是的,在您的代码中它独立运行。但是,只要它没有以某种方式被链接,您就无法预测何时会解决,因此final_result 也是如此。因此expect(final_result).not.to.be.undefined; 可能总是失败。我希望这是有道理的。
  • 那么我正在寻找的正确方法是什么?我想要一个异步作业——它应该在后台运行而不会阻塞当前的承诺——在我仍然设置要解决的父承诺的同时完成。
  • 在这种情况下,由于您使用的是 Bluebird,因此您最好查看Collections 而不是处理个别的承诺。
  • 我已经尝试使用.some,但在负载测试期间遇到了一些问题。好吧,感谢后续 cmets,我想一旦我有一个直接解决我的问题的问题,我最好再问一个问题 :) 向你投赞成票! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-14
  • 1970-01-01
相关资源
最近更新 更多