Làm cách nào tôi có thể đợi trong Node.js (Javascript), tôi cần tạm dừng trong một khoảng thời gian


385

Tôi đang phát triển một giao diện điều khiển như kịch bản cho nhu cầu cá nhân. Tôi cần có thể tạm dừng trong một khoảng thời gian dài, nhưng, từ nghiên cứu của tôi, node.js không có cách nào để dừng lại theo yêu cầu. Thật khó để đọc thông tin của người dùng sau một khoảng thời gian ... Tôi đã thấy một số mã ngoài đó, nhưng tôi tin rằng họ phải có mã khác bên trong để họ làm việc như:

setTimeout(function() {
}, 3000);

Tuy nhiên, tôi cần mọi thứ sau dòng mã này để thực thi sau khoảng thời gian.

Ví dụ,

//start-of-code
console.log('Welcome to My Console,');
some-wait-code-here-for-ten-seconds..........
console.log('Blah blah blah blah extra-blah');
//endcode. 

Tôi cũng đã thấy những thứ như

yield sleep(2000);

Nhưng node.js không nhận ra điều này.

Làm thế nào tôi có thể đạt được sự tạm dừng kéo dài này?


3
nói về bạn đánh dấu một trong những người này là câu trả lời đúng :)
Billybonks

1
@Christopher Allen, Có thể không liên quan, nhưng thực hiện công việc: require("child_process").execSync('php -r "sleep($argv[1]);" ' + seconds);
Haitham Sweilem

- đun npm nút ngủ có thể thực hiện thủ thuật (tuy nhiên, tôi chỉ sử dụng nó để gỡ lỗi)
Julian Soro

Câu trả lời:


211

Cách tốt nhất để làm điều này là chia mã của bạn thành nhiều hàm, như thế này:

function function1() {
    // stuff you want to happen right away
    console.log('Welcome to My Console,');
}

function function2() {
    // all the stuff you want to happen after that pause
    console.log('Blah blah blah blah extra-blah');
}

// call the first chunk of code right away
function1();

// call the rest of the code and have it execute after 3 seconds
setTimeout(function2, 3000);

Nó tương tự như giải pháp của JohnnyHK , nhưng gọn gàng hơn và dễ mở rộng hơn.


7
@LucasSeveryn Bạn đang làm gì đó sai. Đây là một mẫu thiết kế cốt lõi.
Elliot Boneville

Và bạn sẽ làm gì khi bắt đầu chức năng không chỉ là một chức năng, mà là 10 tệp cách mã cần được không đồng bộ hóa?
Cyril Duchon-Doris

10
@ CyrilDuchon-Doris là gì?
AturSams

3
sử dụng câu trả lời của @ machineghost cho một giải pháp dựa trên lời hứa tao nhã không yêu cầu mã tùy chỉnh và hỗ trợ await / async
Dane Macaulay

Đây là async, có nghĩa là nếu hàm1 kết thúc trước 3 giây, chúng bắt đầu chồng chéo lẫn nhau. Sau đó, bạn thậm chí không thể trở lại và nó gần như không bao giờ có thể sử dụng. Cách duy nhất tôi tìm thấy cho đến nay là sử dụngdebugger;
Cristian Traìna

427

Một câu trả lời mới cho một câu hỏi cũ. Hôm nay ( tháng 1 năm 2017 tháng 6 năm 2019) nó dễ dàng hơn nhiều. Bạn có thể sử dụng cú pháp mớiasync/await . Ví dụ:

async function init() {
  console.log(1);
  await sleep(1000);
  console.log(2);
}

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

Để sử dụng async/awaitngoài hộp mà không cần cài đặt và bổ trợ, bạn phải sử dụng nút-v7 hoặc nút-v8, sử dụng --harmonycờ.

Cập nhật tháng 6 năm 2019: Bằng cách sử dụng các phiên bản mới nhất của NodeJS, bạn có thể sử dụng nó ngay lập tức. Không cần phải cung cấp đối số dòng lệnh. Ngay cả Google Chrome cũng hỗ trợ nó ngay hôm nay.

Cập nhật tháng 5 năm 2020: Bạn sẽ sớm có thể sử dụng awaitcú pháp bên ngoài chức năng không đồng bộ. Ở cấp cao nhất như trong ví dụ này

await sleep(1000)
function sleep(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
} 

Đề xuất là trong giai đoạn 3 . Bạn có thể sử dụng nó ngay hôm nay bằng cách sử dụng webpack 5 (alpha),

Thêm thông tin:


5
Tôi nghĩ rằng bạn đã quên awaittừ khóa ở phía trướcsleep(1000)
Ryan Jarvis

6
Đây thực sự nên là câu trả lời, gói node.js ngủ có thể gây rắc rối.
Stuart Allen

4
Giải pháp tốt nhất thực sự
Kostas Siabanis

40
let sleep = ms => new Promise(resolve => setTimeout(resolve, ms));Dành cho những kẻ cuồng oneliner như tôi :)
Predrag Stojadinović

21
let sleep = require('util').promisify(setTimeout);hoạt động trên Node 7.6+ và cải thiện khả năng đọc
BrianHVB

216

Giải pháp ngắn nhất mà không có bất kỳ sự phụ thuộc nào:

await new Promise(resolve => setTimeout(resolve, 5000));

14
"Chiều cao của sự tinh tế là sự đơn giản." - Gian hàng Clare Luce. Đây là câu trả lời tốt nhất, IMO.
arnold

3
Điều này rõ ràng là gần đây hơn nhiều so với các câu trả lời khác, nhưng nó thanh lịch nhất vào năm 2018 giúp công việc được thực hiện trong 1 dòng mà không có bất kỳ tác động nào khác đến mã.
Herick

1
Đây là một người tốt. Bạn phải sử dụng NodeJS 7.6.0 trở lên. Nó sẽ không hoạt động trên các phiên bản cũ hơn.
Ryan Shillington

5
let sleep = require('util').promisify(setTimeout);dài hơn ba ký tự nhưng có thể sử dụng lại và imo dễ đọc hơn
BrianHVB

2
Để tránh khiếu nại eslint, hãy gọi nó resolvethay vì done. Tức làawait new Promise(resolve => setTimeout(resolve, 5000))
Darren Cook

150

Đặt mã mà bạn muốn thực thi sau khi trì hoãn trong cuộc setTimeoutgọi lại:

console.log('Welcome to My Console,');
setTimeout(function() {
    console.log('Blah blah blah blah extra-blah');
}, 3000);

2
Điều này là cực kỳ lộn xộn và nói chung là thực tế tồi tệ, đặc biệt là nếu OP muốn phần còn lại của chương trình chạy sau sự chậm trễ đó. Xem câu trả lời của tôi.
Elliot Boneville

32
@ElliotBonneville Đây chỉ là một ví dụ để minh họa khái niệm này. Rõ ràng là bạn có thể (nên) đưa mã vào một lệnh gọi thay vì sử dụng mã nội tuyến, giống như bất kỳ nơi nào khác.
JohnnyHK

@ChristopherKemp: Hóa ra Node.js có một giải pháp cho việc này được gọi là node-fibers. Kiểm tra nó ra.
Elliot Boneville

Đây là một giải pháp tuyệt vời, đặc biệt nếu bạn không muốn thực thi bất kỳ mã nào, bạn chỉ muốn bắt chước một phương thức "ngủ" trong một vòng lặp. Không có gì sai với ví dụ này.
Halfstop

điều này là hoàn hảo để trì hoãn các yêu cầu đến từ khách hàng, tôi đã sử dụng phương pháp này để kiểm tra các spinners tải của mình ở phía khách hàng
moein rahimi

145

Đây là một kỹ thuật chặn đơn giản:

var waitTill = new Date(new Date().getTime() + seconds * 1000);
while(waitTill > new Date()){}

chặn trong chừng mực vì sẽ không có gì khác xảy ra trong tập lệnh của bạn (như cuộc gọi lại). Nhưng vì đây là một kịch bản console, có thể nó là thứ bạn cần!


27
kinh khủng hay không, nó đơn giản wait, nó chặn và nó hoạt động cho một số mục đích thử nghiệm. Chính xác những gì tôi đang tìm kiếm.
Clijsters

8
trả lời hoàn hảo câu hỏi mà không cần libs bên thứ 3, và rất đơn giản. Tuy nhiên mọi người nói "khủng khiếp" .... Điều này thật tuyệt, ví dụ như để mô phỏng tải CPU nặng, v.v ... Btw rất giống với phpied.com/s ngủ
Don Cheadle

2
Ngoài ra, đây là cách tiếp cận bắt buộc nếu bạn đang cố gắng mô phỏng thứ gì đó sẽ làm chậm vòng lặp sự kiện, do đó cũng làm chậm người dùng / kết nối khác. Thêm các cuộc gọi lại bị trì hoãn sẽ không ảnh hưởng đến người dùng / kết nối khác.
Don Cheadle

13
Đây là một spin-wait.
Mike Atlas

7
@Ali đó dường như là mục tiêu.
Félix Gagnon-Grenier

63

Trên nút 7.6.0 trở lên

Nút hỗ trợ chờ đợi nguyên bản:

const sleep = (waitTimeInMs) => new Promise(resolve => setTimeout(resolve, waitTimeInMs));

sau đó nếu bạn có thể sử dụng các chức năng không đồng bộ:

await sleep(10000); // sleep for 10 seconds

hoặc là:

sleep(10000).then(() => {
  // This will execute 10 seconds from now
});

Trên các phiên bản Node cũ hơn (câu trả lời gốc)

Tôi muốn có một giấc ngủ không đồng bộ hoạt động trong Windows & Linux, mà không làm hỏng CPU của tôi với một vòng lặp dài. Tôi đã thử gói ngủ nhưng nó sẽ không cài đặt trên hộp Windows của tôi. Tôi đã kết thúc bằng cách sử dụng:

https://www.npmjs.com/package/system-s ngủ

Để cài đặt nó, gõ:

npm install system-sleep

Trong mã của bạn,

var sleep = require('system-sleep');
sleep(10*1000); // sleep for 10 seconds

Hoạt động như một lá bùa.


1
câu trả lời tuyệt vời cảm ơn - nó đã tạo ra một số mã không thể thực hiện được - đây KHÔNG phải là một sự chờ đợi
danday74

1
Trong nghiên cứu sâu hơn, mô-đun này dựa trên deasync, được rẽ nhánh từ một repo dithync khác. Các repo ban đầu cảnh báo không sử dụng nó vì nó là một hack. Nó hoạt động nhưng không phải trên tất cả các nền tảng vì vậy nếu bạn cần một giải pháp đa nền tảng, hãy tránh giải pháp này.
danday74

1
vâng, tôi chưa bao giờ trải nghiệm probs với nó và nó rất tuyệt cho nhà phát triển - nếu hệ thống không hoạt động, giấc ngủ sẽ quay trở lại trạng thái chờ đợi, điều này sẽ đóng băng việc thực thi mã
danday74

1
Gói này không hoạt động trên Mac OS và do đó không tương thích chéo và do đó không thể hoạt động. Xem github.com/jochemstoel/nodejs-system-sadd/issues/4
nuzzolilo

1
@Nuzzolilo Thật kỳ lạ. Chúng tôi có một nhà phát triển trên Mac OS và anh ấy không bao giờ đề cập đến bất cứ điều gì sai. Tôi nghi ngờ đây là phiên bản Mac OS cụ thể. Tôi cũng đã cập nhật câu trả lời này vì về cơ bản giấc ngủ được tích hợp vào các phiên bản mới hơn của NodeJS.
Ryan Shillington

62

Chức năng ngủ đơn giản và thanh lịch sử dụng Javascript hiện đại

function sleep(millis) {
    return new Promise(resolve => setTimeout(resolve, millis));
}

Không phụ thuộc, không có địa ngục gọi lại; đó là nó :-)


Xem xét ví dụ được đưa ra trong câu hỏi, đây là cách chúng ta sẽ ngủ giữa hai bản ghi giao diện điều khiển:

async function main() {
    console.log("Foo");
    await sleep(2000);
    console.log("Bar");
}

main();

"Hạn chế" là chức năng chính của bạn bây giờ cũng phải asyncnhư vậy. Nhưng, xem xét bạn đã viết mã Javascript hiện đại, có lẽ bạn (hoặc ít nhất là nên!) Sử dụng async/ awaittrên toàn bộ mã của bạn, vì vậy đây thực sự không phải là vấn đề. Tất cả các trình duyệt hiện đại ngày nay đều hỗ trợ nó.

Cung cấp một cái nhìn sâu sắc về sleepchức năng cho những người không quen sử dụng async/awaitvà vận hành mũi tên béo, đây là cách viết dài dòng:

function sleep(millis) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () { resolve(); }, millis);
    });
}

Tuy nhiên, sử dụng toán tử mũi tên béo làm cho nó thậm chí còn nhỏ hơn (và thanh lịch hơn).


1
Bạn cũng có thể viết hàm ngủ mà không cần asyncvà để mọi thứ khác giống nhau. Nó có thể rõ ràng hơn với asyncmặc dù.
Kevin Peña

Bắt tốt, @ KevinPeña. Vấn đề thực tế, tôi nghĩ rằng tôi thích nó mà không có async. Chỉnh sửa câu trả lời của tôi với đề nghị của bạn. Tôi không nghĩ rằng nó làm cho mã rõ ràng hơn; thay vào đó, tôi sẽ dùng đến JSDoc.
Lucio Paiva

8
Tôi muốn có một lớp lót sau trong kịch bản của mình:const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
korya

46

Bạn có thể sử dụng www.npmjs.com/package/s ngủ này

var sleep = require('sleep');
sleep.sleep(10); // sleep for ten seconds

4
Nó hoạt động tốt trên MacOS, nhưng nó gặp lỗi CentOSdo lỗi node_gyp . Có vẻ như không di động.
AechoLiu

1
có lẽ vấn đề gây ra không phải do hệ điều hành, mà là do xây dựng nút
Aleksej

34

Câu hỏi này khá cũ, nhưng gần đây V8 đã thêm Máy phát điện có thể thực hiện những gì OP yêu cầu. Các trình tạo thường dễ sử dụng nhất cho các tương tác không đồng bộ với sự hỗ trợ của thư viện như tạm ngưng hoặc chạy gen .

Đây là một ví dụ sử dụng đình chỉ:

suspend(function* () {
    console.log('Welcome to My Console,');
    yield setTimeout(suspend.resume(), 10000); // 10 seconds pass..
    console.log('Blah blah blah blah extra-blah');
})();

Đọc liên quan (bằng cách tự quảng cáo không biết xấu hổ): Thỏa thuận lớn với Máy phát điện là gì? .


2
Câu trả lời hay - Nhưng nên đọcyield setTimeout(suspend.resume(), 10000);
edhubbell

1
Cảm ơn, @edhubbell. Câu trả lời này được dựa trên một phiên bản đình chỉ rất cũ, nhưng bạn nói đúng về vấn đề mới nhất. Tôi sẽ cập nhật câu trả lời.
jmar777

phiên bản này của nút này để làm gì?
danday74

1
@ danday74 Tôi không thể nhớ chính xác khi nào chúng không được gắn cờ, nhưng chúng đã xuất hiện từ v0.12 phía sau --harmonycờ và theo node.green, chúng ít nhất có sẵn mà không có bất kỳ cờ nào kể từ v4.8.4: node.green/#ES2015-fifts-generators-basic-feftality . Tuy nhiên, xin lưu ý rằng async/awaitcú pháp mới hơn cung cấp một giải pháp tốt hơn cho vấn đề này ngay bây giờ, không cần thêm các thư viện như suspend. Xem câu trả lời này cho một ví dụ: stackoverflow.com/a/41957152/376789 . Các chức năng Async có sẵn (không có cờ) kể từ v7.10.
jmar777

20

Trên Linux / nodejs, nó hoạt động với tôi:

const spawnSync = Yêu cầu ('child_ process'). spawnSync;

var ngủ = spawnSync ('ngủ', [1.5]);

Nó đang chặn, nhưng nó không phải là một vòng lặp chờ đợi bận rộn.

Thời gian bạn chỉ định là tính bằng giây nhưng có thể là một phần nhỏ. Tôi không biết nếu các hệ điều hành khác có lệnh tương tự.


sleepcó khá nhiều ở khắp mọi nơi và là một utiltiy arround kể từ những ngày đầu UNIX en.wikipedia.org/wiki/S ngủ_% 28Unix% 29 . Chỉ có os "không hiếm" mà nó có thể không tồn tại là cửa sổ (tuy nhiên ở đó bạn có thể thửchild_process.spawnSync('timeout', ['/T', '10'])
nhân

17

Nếu bạn muốn "đánh gôn", bạn có thể tạo một phiên bản ngắn hơn của một số câu trả lời khác tại đây:

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

Nhưng thực sự câu trả lời lý tưởng theo ý kiến ​​của tôi là sử dụng utilthư viện của Node và promisifychức năng của nó , được thiết kế cho chính xác loại điều này (tạo các phiên bản dựa trên lời hứa của các công cụ không dựa trên lời hứa trước đây):

const util = require('util');
const sleep = util.promisify(setTimeout);

Trong cả hai trường hợp, bạn có thể tạm dừng đơn giản bằng cách sử dụng awaitđể gọi sleephàm của mình :

await sleep(1000); // sleep for 1s/1000ms

Trên thực tế, bằng cách sử dụng produc.promisify, không thể gọi giấc ngủ mà không cung cấp một cuộc gọi lại. nodejs.org/api/ Kẻ
Howie

1
Bạn đang thiếu await. Nó tạo ra một cuộc gọi lại, tạm dừng mọi thứ và sau đó khởi động lại mã khi cuộc gọi lại đó trở lại. Cuộc gọi lại trả về với một giá trị, nhưng chúng tôi không quan tâm đến nó trong trường hợp này, vì vậy không có gì ở bên trái await.
máy

1
viết nó thành một dòng để viết mã golf;) const ngủ = request ('produc'). promisify (setTimeout);
Fabian

14

Gần đây tôi đã tạo ra sự trừu tượng đơn giản hơn được gọi là Wait.for để gọi các hàm async trong chế độ đồng bộ hóa (dựa trên các sợi nút). Ngoài ra còn có một phiên bản dựa trên ES6 Generators sắp tới.

https://github.com/luciotato/waitfor

Sử dụng Wait.for , bạn có thể gọi bất kỳ chức năng async nodejs tiêu chuẩn nào, như thể đó là một chức năng đồng bộ hóa, mà không chặn vòng lặp sự kiện của nút.

Bạn có thể mã tuần tự khi bạn cần, đó là, (tôi đoán) hoàn hảo để đơn giản hóa các tập lệnh của bạn cho sử dụng cá nhân.

sử dụng Wait.cho mã của bạn sẽ là:

require('waitfor')

..in a fiber..
//start-of-code
console.log('Welcome to My Console,');
wait.miliseconds(10*1000); //defined in waitfor/paralell-tests.js - DOES NOT BLOCK
console.log('Blah blah blah blah extra-blah');
//endcode. 

Ngoài ra, bất kỳ chức năng async nào cũng có thể được gọi trong chế độ Đồng bộ hóa . Kiểm tra các ví dụ.


TypeError: Object #<Object> has no method 'miliseconds'
CaffeineAddtions

bình luận nói: "// được xác định trong Waitfor / paralell-tests.js" lấy nó từ tệp đó.
Lucio M. Tato

2
sau khi tôi nhận được nó, wait.for/paralell-tests.jstôi đã gặp một lỗi khác liên quan đến các thuộc tính không xác định, v.v. Vì vậy, tôi cũng cần phải sao chép chúng. Tại sao bạn không tổ chức mã theo cách mà điều này sẽ không được yêu cầu?
dùng907860

Wait.for và các giải pháp sợi khác đã mở ra một thế giới hoàn toàn mới với tôi! Tôi sẽ bỏ phiếu này một triệu lần nếu tôi có thể. Mặc dù hầu hết các cộng đồng nodejs phản đối các sợi, tôi nghĩ rằng chúng là một bổ sung tuyệt vời và chắc chắn có vị trí của chúng khi nói đến địa ngục gọi lại.
Levi Roberts

7

Vì, công cụ javascript (v8) chạy mã dựa trên chuỗi các sự kiện trong hàng đợi sự kiện, không có gì nghiêm ngặt khi javascript kích hoạt chính xác việc thực thi sau thời gian quy định. Đó là, khi bạn đặt một vài giây để thực thi mã sau đó, việc kích hoạt mã hoàn toàn dựa trên chuỗi trong hàng đợi sự kiện. Vì vậy, việc kích hoạt thực thi mã có thể mất nhiều thời gian hơn quy định.

Vì vậy, Node.js theo sau,

process.nextTick()

để chạy mã sau thay vì setTimeout (). Ví dụ,

process.nextTick(function(){
    console.log("This will be printed later");
});

2

Với các hỗ trợ ES6 Promise, chúng tôi có thể sử dụng chúng mà không cần bất kỳ sự trợ giúp nào của bên thứ ba.

const sleep = (seconds) => {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, (seconds * 1000));
    });
};

// We are not using `reject` anywhere, but it is good to
// stick to standard signature.

Sau đó sử dụng nó như thế này:

const waitThenDo(howLong, doWhat) => {
    return sleep(howLong).then(doWhat);
};

Lưu ý rằng doWhatchức năng trở thành cuộc resolvegọi lại trong new Promise(...).

Cũng lưu ý rằng đây là giấc ngủ ASYNCHRONOUS. Nó không chặn vòng lặp sự kiện. Nếu bạn cần chặn giấc ngủ, hãy sử dụng thư viện này để nhận ra việc chặn giấc ngủ với sự trợ giúp của các ràng buộc C ++. (Mặc dù nhu cầu ngủ chặn trong Node như môi trường không đồng bộ là rất hiếm.)

https://github.com/erikdubbelboer/node-s ngủ


1
let co = require('co');
const sleep = ms => new Promise(res => setTimeout(res, ms));

co(function*() {
    console.log('Welcome to My Console,');
    yield sleep(3000);
    console.log('Blah blah blah blah extra-blah');
});

Mã này ở trên là tác dụng phụ của việc giải quyết vấn đề địa ngục gọi lại không đồng bộ của Javascript. Đây cũng là lý do tôi nghĩ rằng làm cho Javascript trở thành một ngôn ngữ hữu ích trong phần phụ trợ. Thực tế đây là cải tiến thú vị nhất được giới thiệu cho Javascript hiện đại theo ý kiến ​​của tôi. Để hiểu đầy đủ về cách thức hoạt động của nó, cách thức hoạt động của máy phát điện cần phải được hiểu đầy đủ. Các functiontừ khóa theo sau là một *được gọi là một chức năng máy phát điện trong Javascript hiện đại. Gói npm cocung cấp chức năng chạy để chạy máy phát điện.

Về cơ bản, hàm tạo đã cung cấp một cách để tạm dừng việc thực thi một hàm bằng yieldtừ khóa, đồng thời, yieldtrong một hàm tạo giúp cho việc trao đổi thông tin giữa bên trong máy phát và người gọi. Điều này cung cấp một cơ chế cho người gọi trích xuất dữ liệu từ một promisecuộc gọi không đồng bộ và chuyển dữ liệu đã giải quyết trở lại máy phát. Thực tế, nó làm cho một cuộc gọi không đồng bộ đồng bộ.


Mặc dù mã này có thể trả lời câu hỏi, việc cung cấp ngữ cảnh bổ sung về cách thức và / hoặc lý do giải quyết vấn đề sẽ cải thiện giá trị lâu dài của câu trả lời.
Vịt Donald

Cảm ơn @DonaldDuck. Mã trong câu trả lời của tôi có lẽ là phần thú vị nhất của cải tiến trong Javascript. Tôi rất ngạc nhiên khi một số người siêu thông minh nghĩ về cách này để giải quyết vấn đề địa ngục gọi lại.
Qian Chen


0

Nếu bạn chỉ cần tạm dừng cho mục đích thử nghiệm, bạn thực hiện luồng hiện tại, hãy thử điều này:

function longExecFunc(callback, count) {

    for (var j = 0; j < count; j++) {
        for (var i = 1; i < (1 << 30); i++) {
            var q = Math.sqrt(1 << 30);
        }
    }
    callback();
}
longExecFunc(() => { console.log('done!')}, 5); //5, 6 ... whatever. Higher -- longer

0

đơn giản, chúng tôi sẽ đợi 5 giây để một số sự kiện xảy ra (điều đó được biểu thị bằng biến đã thực hiện được đặt thành đúng ở một nơi khác trong mã) hoặc khi hết thời gian, chúng tôi sẽ kiểm tra sau mỗi 100ms

    var timeout=5000; //will wait for 5 seconds or untildone
    var scope = this; //bind this to scope variable
    (function() {
        if (timeout<=0 || scope.done) //timeout expired or done
        {
            scope.callback();//some function to call after we are done
        }
        else
        {
            setTimeout(arguments.callee,100) //call itself again until done
            timeout -= 100;
        }
    })();

0

Đối với một số người, câu trả lời được chấp nhận không hoạt động, tôi đã tìm thấy câu trả lời khác này và nó đang hoạt động với tôi: Làm cách nào tôi có thể chuyển tham số cho cuộc gọi lại setTimeout ()?

var hello = "Hello World";
setTimeout(alert, 1000, hello); 

'xin chào' là tham số được truyền, bạn có thể vượt qua tất cả các tham số sau khi hết thời gian. Cảm ơn @Fabio Phms đã trả lời.


0

Thay vì thực hiện tất cả các setTimeout này, ngủ và nhiều thứ khác, tốt hơn là sử dụng

const delay = require('delay');
await delay(2000); // will wait for 2 seconds before executing next line of code

Bạn có thể giải thích 'sự chậm trễ' là gì và liên kết đến các tài liệu của nó không? Tại sao nó tốt hơn?
boycy

-2

Các câu trả lời khác rất hay nhưng tôi nghĩ tôi sẽ thực hiện một chiến thuật khác.

Nếu tất cả những gì bạn thực sự tìm kiếm là làm chậm một tệp cụ thể trong linux:

 rm slowfile; mkfifo slowfile; perl -e 'select STDOUT; $| = 1; while(<>) {print $_; sleep(1) if (($ii++ % 5) == 0); }' myfile > slowfile  &

nút myprog Slowfile

Điều này sẽ ngủ 1 giây mỗi năm dòng. Chương trình nút sẽ đi chậm như người viết. Nếu nó đang làm những việc khác họ sẽ tiếp tục ở tốc độ bình thường.

Mkfifo tạo ra một đường ống vào trước xuất trước. Đó là những gì làm cho công việc này. Dòng perl sẽ viết nhanh như bạn muốn. $ | = 1 nói không đệm đầu ra.


-3

Tôi kết hợp lại, sau khi đọc câu trả lời trong câu hỏi này, một hàm đơn giản cũng có thể thực hiện gọi lại, nếu bạn cần điều đó:

function waitFor(ms, cb) {
  var waitTill = new Date(new Date().getTime() + ms);
  while(waitTill > new Date()){};
  if (cb) {
    cb()
  } else {
   return true
  }
}

-4

Để biết thêm thông tin về

yield sleep(2000); 

bạn nên kiểm tra Redux-Saga . Nhưng nó là cụ thể cho sự lựa chọn của bạn về Redux làm khung mô hình của bạn (mặc dù hoàn toàn không cần thiết).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.