开始时的额外承诺和最后的额外承诺

时间:2017-09-18 17:32:51

标签: javascript node.js promise

承诺的新意,所以随意大肆宣传。

我正在写一个函数" extra_promises_at_start_and_end"返回承诺做某事。

此函数可能立即知道它将失败(即:返回被拒绝的承诺)。问题1:是否有类似Promise.give_me_a_rejected_promise(..)的内容,或者我是否必须创建一个承诺并拒绝它,就像我的代码一样?

同样,我的功能" extra_promises_at_start_and_end"调用返回promises的其他函数。在这个异步链接的工作结束时,我需要进行一些最终处理。问题2a / 2b:由于我的函数返回了一个promise,我需要创建一个承诺来完成最后一点工作。这是正确的,我需要创建一个承诺并立即接受或拒绝它吗?是否有Promise.give_me_a_rejected_promise(..)。

我的代码按预期工作,只是觉得我遗漏了一些东西,因此生成冗余代码。

有问题的代码:

// this is the function that may have redundant code
// see question 1 and 2
function extra_promises_at_start_and_end() {
    // fake out some module scope variable that indicates if this call is allowed to proceed or not
    let ok_to_proceed = Math.random() > 0.5

    // this function "extra_promises_at_start_and_end returns" a promise, 
    // Question 1: I need to create a Promise just to reject it immediatly?
    if (!ok_to_proceed) {
        return new Promise((resolve, reject) => { reject("failed before starting anything") }) // feels wrong
    }

    // do 5 things in sequence
    return another_module_promise_to_do_something(1).then(() => {
        return another_module_promise_to_do_something(2)
    }).then(() => {
        return another_module_promise_to_do_something(3)
    }).then(() => {
        return another_module_promise_to_do_something(4)
    }).then(() => {
        return another_module_promise_to_do_something(5)
    }).then(() => {
        // need to do something after the above 5 tasks are done, 

        console.log("doing something after all 5 things are done")

        // this function "extra_promises_at_start_and_end" returns a promise, 
        // Question 2a: I need to create a promise just to resolve it immediatly?
        return new Promise((resolve, reject) => { resolve(); }) // feels wrong
        }).catch((id) => {
            // this function extra_promises_at_start_and_end returns a promise, 
            // Question 2b: I need to create one just to reject it immediatly?
            return new Promise((resolve, reject) => { reject(id); }) // feels wrong
        })
}

此代码的调用者期待一个承诺。

// run the test
console.log("calling something that will return a promise to let me know when it's done");
extra_promises_at_start_and_end()
    .then(() => {
        console.log("done :)")
    }).catch((id) => { console.log("failed id = " + id) })

最后,用于测试我的函数的存根

// pretend this is a complex task (ie: not suitable for inlining)
// done by some other module
// it returns a promise
function another_module_promise_to_do_something(id) {
    console.log("starting " + id)

    let P = new Promise((resolve, reject) => {
        console.log("  inside promise " + id)

        setTimeout(() => {
            if (Math.random() > 0.1) {
                console.log("  finished " + id);
                resolve();
            } else {
                console.log("  failed " + id)
                reject(id);
            }
        }, Math.random() * 1000)
    })

    return P;
}

如果这是应该完成的方式,那么请告诉我,我将停止寻找使用promises的正确方法。

3 个答案:

答案 0 :(得分:0)

我学到的是:

  • Promise.resolve(value)方法返回使用给定值解析的Promise对象。所以任何调用我的函数的人都可以对响应进行处理。

  • Promise.reject(reason)方法返回一个Promise对象,该对象因给定原因而被拒绝。所以任何链接都会根据需要失败。

  • 然后将任何返回值封装在一个promise中。这样的感觉掩盖了意图。所以不要使用。

我的新功能如下:

function promise_something() {
    // fake out some module scope variable that indicates if this call is allowed to proceed or not
        let ok_to_proceed = Math.random() > 0.5



 if (!ok_to_proceed) {
        return Promise.reject("failed before starting anything") 
    }

    // do 5 things in sequence
    return another_module_promise_to_do_something(1).then(() => {
        return another_module_promise_to_do_something(2)
    }).then(() => {
        return another_module_promise_to_do_something(3)
    }).then(() => {
        return another_module_promise_to_do_something(4)
    }).then(() => {
        return another_module_promise_to_do_something(5)
    }).then(() => {
        // need to do something after the above 5 tasks are done, 

        console.log("doing something after all 5 things are done")

        return Promise.resolve()
}

答案 1 :(得分:-1)

username = 'username' password = 'password' proxies = {'http': 'http://...., 'https': 'https://....} page = requests.get(URL, proxies=proxies) 的{​​{1}}和then()函数返回catch()

你最后一大块代码确实是多余的。如果您需要在Promise的第5次链接调用后进行任何处理,则可以链接另一个Promise

这里有一个更简单的代码版本来说明:

then()

您可以使用then()返回被拒绝的const countFromOneToFive = () => { if (Math.random() > 0.5) { return Promise.reject("Cosmic radiation ruined your promises. Great."); } return Promise.resolve([]) .then((countToFive) => { countToFive.push(1); return countToFive; }) .then((countToFive) => { countToFive.push(2); return countToFive; }) .then((countToFive) => { countToFive.push(3); return countToFive; }) .then((countToFive) => { countToFive.push(4); return countToFive; }) .then((countToFive) => { countToFive.push(5); return countToFive; }); }; countFromOneToFive() .then((countToFive) => { countToFive.forEach((number) => console.log(number)); }) .catch((error) => { console.log(error, "Curses!"); });。这在底部的catch语句中处理。

您可以根据需要使用尽可能多的Promise.reject()次调用来完成所有处理。您可以在最终Promise之后返回then()。从那里开始,像对待任何承诺一样对待它,并在您认为合适时添加then()Promise

答案 2 :(得分:-1)

  

1:是否有类似Promise.give_me_a_rejected_promise(..)的东西,或者我是否必须创建一个承诺并拒绝它,就像我的代码一样?

喜欢Promise.reject(err)

  

//问题2a:我需要创建一个承诺,立即解决它?

在代码中写入它的位置在promise链中。您根本不需要做任何事情(在该上下文中),返回已解决的Promise,除非throw可能。

此承诺将解析为您返回的任何值,undefined除外。如果您返回undefined (明确或隐含地),此承诺将在Promise链中解析为之前的最后一个值。
只有当您需要明确解析为undefined时,您才需要return Promise.resolve()

  

//问题2b:我需要创建一个只是立即拒绝它吗?

仍然在Promise链中:由于被拒绝的值就像是同步代码中抛出的错误,因此您需要做的就是throw

但在你提出的背景下,这是毫无意义的。为什么要捕获一个Error,只是为了立即抛出相同的Error,而不在catch块中做任何其他事情。

所以你的代码可能就像

function extra_promises_at_start_and_end() {
    // fake out some module scope variable that indicates if this call is allowed to proceed or not
    let ok_to_proceed = Math.random() > 0.5

    if (!ok_to_proceed) {
        return Promise.reject("failed before starting anything");
    }

    // do 5 things in sequence
    return another_module_promise_to_do_something(1)
        .then(() => another_module_promise_to_do_something(2))
        .then(() => another_module_promise_to_do_something(3))
        .then(() => another_module_promise_to_do_something(4))
        .then(() => another_module_promise_to_do_something(5))
        .then(() => {
            // need to do something after the above 5 tasks are done, 

            console.log("doing something after all 5 things are done")

            return null; //so the previous value is no longer propagated by this Promise
        })
        //.catch(id => { throw id }) //is pointless.
}
  

当你说“这个承诺会解决你返回的任何价值”时。所以返回新的Promise((解决,拒绝)=> {resolve 100})。然后.... blaw blaw blaw与100.then一起... blaw blaw blaw?

不完全是。在Promise链中,返回一个简单的值,如100或一个解析为100 的Promise(如return Promise.resolve(100)在结果中是等效的...

var foo1 = somePromise.then(() => {
    //do something
    return 100
})
//is equivalent in result to
var foo2 = somePromise.then(() => {
    //do something
    return Promise.resolve(100);
})
//or to
var foo3 = somePromise.then(() => {
    //do something
    return new Promise(resolve => resolve(100));
})

foo1foo2foo3都是100完成后解析为somePromise值的承诺。这相当于结果。

...但您无法在号码上拨打then()

//you can do
somePromise.then(() => {
    //do something
    return 100
}).then(...)

//or sometimes you want to do
somePromise.then((value) => {
   //usually because you need `value` inside `.then(...)`
    return somethingAsync().then(...)
})

//but you can NOT do 
somePromise.then(() => {
    //do something
    return 100.then(...)
})