如何使用setTimeout和promises使这个JS代码更具功能性?

时间:2017-07-07 20:04:25

标签: javascript node.js asynchronous functional-programming

我试图学习如何使用更多功能和更少的循环进行编码,并且只是以更多功能的方式。我想在调用connectBing之间实现一段时间。我想知道是否有可能不使用i变量并且仍然在迭代之间获得1秒的时间。我的代码目前有效,但我正在寻找其他方法来编写它而不使用i。

这是我的代码:

// MAIN
getAllPosts().then((posts) => {
    posts
        .forEach( (post, i) => {
            setTimeout(() => {
                connectBing(anchorText,console.log).then()
            } ,i * 1000)
        })

// CONNECT TO BING WITH KW AND DO SOMETHING
function connectBing(anchorText,doSomethingWithBing) {
    var deferred = q.defer();                                                                   
    request('https://www.cnn.com/search?q=' + anchorText, function (error, response, body) {    
        error ? console.log('error:', error) :                                                    
        console.log('statusCode:', response && response.statusCode);                              
        (doSomethingWithBing) ? doSomethingWithBing(body) : "You didn't give connectBing anything to do!"       
    })
    return deferred.promise                 
}

1 个答案:

答案 0 :(得分:1)

您可以获取一组异步函数,并将每个函数链接到另一个函数。我将使用原生承诺来演示,您可以将其映射到您正在使用的库。

首先创建一个接收异步函数数组的函数。它将一个接一个地链接,返回最后一个:

function chainAsyncFns(fns) {
    // Ensure we have at least one promise to return

    let promise = Promise.resolve();

    fns.forEach(fn => promise = promise.then(fn));

    return promise;
}

然后对于每个帖子,创建一个异步函数,它将调用connectBing然后等待超时:

function connectBing() {
    // Pretend we are connecting to a data source

    return Promise.resolve();
}

function delay(ms) {
    // Return a promise that resolves when the timeout is up

    return new Promise(resolve => setTimeout(resolve, ms));
}

let fns = posts.map(post => () => {
    return connectBing()
        .then(() => delay(1000))
        .catch(() => console.log('error'));
});

将函数链接到一个接一个地运行:

chainAsyncFns(fns).then(() => console.log('done'));