【问题标题】:How to use promise with for loop and $.get request?如何将 promise 与 for 循环和 $.get 请求一起使用?
【发布时间】:2022-01-28 01:18:45
【问题描述】:

这是我第一次使用 Promise,所以我敢肯定这里有一些非常愚蠢的错误。我想要做的是发送一个在 for 循环中的 http 请求。

在没有承诺的情况下执行此操作时,我可以正常运行此循环并且一切正常。但是,当我使用 promise 执行此操作时,它只返回一个对象(应该是多个,因为它发送多个请求)

这是我的代码

function run(o,initialvalue){
        const test = new Promise( (resolve,reject) => {
            const collectionCountUrl = 'https://x.io/rpc/Query?q=%7B%22%24match%22%3A%7B%22collectionSymbol%22%3A%22'+o.name+'%22%7D%2C%22%24sort%22%3A%7B%22takerAmount%22%3A1%2C%22createdAt%22%3A-1%7D%2C%22%24skip%22%3A'+initialvalue+'%2C%22%24limit%22%3A500%7D'
            promises = []
            for(i=0; i < o.count(/*in this case 60, so 3 requests*/); i+= 20){
                $.get(collectionCountUrl).success(resolve).fail(reject) // This should be sending multiple of the requests above, correct? ^
            }
        })
    
        test.then(function(data){
            console.log(data) // this should return the data from each request? im not sure
        })
    }

我尝试查看这篇文章,看看我是否设置了错误的 for 循环,但我不认为我是。 Promise for-loop with Ajax requests

【问题讨论】:

    标签: javascript


    【解决方案1】:

    一个承诺是一个单一的结果。您必须将每个请求包装在单独的 Promise 中(将构造函数调用移动到循环中),并将 Promise 存储在数组中。

    然后,您可以使用聚合器方法,如 Promise.all(其他为 Promise.allSettledPromise.racePromise.any)来获得一组结果的单一承诺,您可以等待。

    像这样:

    function run(o,initialvalue){
        const collectionCountUrl = 'https://x.io/rpc/Query?q=%7B%22%24match%22%3A%7B%22collectionSymbol%22%3A%22'+o.name+'%22%7D%2C%22%24sort%22%3A%7B%22takerAmount%22%3A1%2C%22createdAt%22%3A-1%7D%2C%22%24skip%22%3A'+initialvalue+'%2C%22%24limit%22%3A500%7D'
        const promises = []
    //  ^^^^^----+--- don't forget to declare all your variables
    //      vvv--+
        for(let i=0; i < o.count(/*in this case 60, so 3 requests*/); i+= 20){
            promises.push(new Promise( (resolve,reject) => {
                $.get(collectionCountUrl).success(resolve).fail(reject) 
            }))
        }
        
        //You've got an array of promises, let's convert it to a single one that resolves when everything's done:
        const test = Promise.all(promises)
    
        test.then(function(data){
            //This will run when all the requests have succeeded
            //`data` is an array of results
            console.log(data) 
        })
    }
    

    这可行,但还有更好的方法!

    jQuery 的$.Deferred 对象(就像你从$.get 得到的那个)也有一个.then() 方法,就像promises 一样,虽然它不是一个真实 的promise,但你可以使用就像是这样。这样的对象被称为thenables

    所以,不是这个东西……

    promises.push(new Promise( (resolve,reject) => {
        $.get(collectionCountUrl).success(resolve).fail(reject) 
    }))
    

    ...你可以这样做:

    promises.push( $.get(collectionCountUrl) )
    

    所以,这是最终的代码:

    function run(o,initialvalue){
        const collectionCountUrl = 'https://x.io/rpc/Query?q=%7B%22%24match%22%3A%7B%22collectionSymbol%22%3A%22'+o.name+'%22%7D%2C%22%24sort%22%3A%7B%22takerAmount%22%3A1%2C%22createdAt%22%3A-1%7D%2C%22%24skip%22%3A'+initialvalue+'%2C%22%24limit%22%3A500%7D'
        const promises = []
        for(let i=0; i < o.count(/*in this case 60, so 3 requests*/); i+= 20){
            promises.push( $.get(collectionCountUrl) )
        }
        
        //You've got an array of promises, let's convert it to a single one that resolves when everything's done:
        const test = Promise.all(promises)
    
        test.then(function(data){
            //This will run when all the requests have succeeded
            //`data` is an array of results
            console.log(data) 
        })
    }
    

    【讨论】:

      猜你喜欢
      • 2019-07-02
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多